码迷,mamicode.com
首页 > 其他好文 > 详细

文件传送

时间:2018-12-01 23:45:15      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:error   [1]   python   ref   传输   情况   导入   对象   split   

技术分享图片

简单版

服务端

import socket
import subprocess
import struct
import json
import os

share_dir = r‘F:\project\book\chapter6\文件传输\简单版本\server\share‘

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # (如果机器中存在,重新用端口)应对端口占用报错情况

phone.bind(("127.0.0.1", 9909))   # 127.0.0.1本地地址,端口范围0-65535:其中0-1024给操作系统使用

phone.listen(5)   # 5代表最大挂起连接数

print("starting...")
while True:  # 循环链接
    conn, client = phone.accept()  # conn套接字对象

    while True:    # 通讯循环
        try:
            # 1、接收命令  (命令:执行系统命令)
            res = conn.recv(8096)  # b‘get a.txt

            # 2、解析命令,提取相应的命令参数
            cmds = res.decode("utf-8").split()
            filename = cmds[1]

            # 3、以读的方式打开文件,读取文件内容,发送给客户端

            # 第一步:制作固定长度的报头(import struct)
            header_dic = {
                "filename": filename,
                "md5": "xxdxxx",
                "file_size": os.path.getsize(r"%s/%s" % (share_dir, filename))
            }
            header_json = json.dumps(header_dic)

            header_bytes = header_json.encode("utf-8")

            # 第二步:先发送报头的长度
            conn.send(struct.pack("i", len(header_bytes)))

            # 第三步:再发报头
            conn.send(header_bytes)

            # 第四步:再发送真实的数据
            with open("%s/%s" % (share_dir, filename), "rb")as f:
                # conn.send(f.read())   # 如果文件太大,会占满内存
                for line in f:
                    conn.send(line)

        except ConnectionRefusedError:
            break

    conn.close()

phone.close()

 客户端

import socket
import struct
import json

download_dir = r"F:\project\book\chapter6\文件传输\简单版本\client\download"

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

phone.connect(("127.0.0.1", 9909))  # phone相当于服务端的conn

while True:
    # 1、发命令
    cmd = input(">> ").strip()  # get a.txt
    if not cmd:
        continue
    phone.send(cmd.encode("utf-8"))

    # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户端的新文件中
    # 第一步:先收报头的长度
    header = phone.recv(4)
    header_size = struct.unpack("i", header)[0]

    # 第二步:再接收报头信息
    header_bytes = phone.recv(header_size)

    # 第三步:从报头中解析出对真实数据的描述信息
    header_json = header_bytes.decode("utf-8")
    header_dic = json.loads(header_json)
    print(header_dic)
    file_size = header_dic["file_size"]
    filename = header_dic["filename"]

    # 第四步:接受真实的数据
    with open("%s/%s" % (download_dir, filename), "wb")as f:
        recv_size = 0
        while recv_size < file_size:
            line = phone.recv(1024)
            f.write(line)
            recv_size += len(line)
            print("总大小:%s  已下载大小:%s" % (file_size, recv_size))

phone.close()

  


函数版

服务端

import socket
import subprocess
import struct
import json
import os

share_dir = r‘F:\project\book\chapter6\文件传输\函数版本\server\share‘


def get(conn, cmds):
    filename = cmds[1]
    # 3、以读的方式打开文件,读取文件内容,发送给客户端
    # 第一步:制作固定长度的报头(import struct)
    header_dic = {
        "filename": filename,
        "md5": "xxdxxx",
        "file_size": os.path.getsize(r"%s/%s" % (share_dir, filename))
    }
    header_json = json.dumps(header_dic)
    header_bytes = header_json.encode("utf-8")

    # 第二步:先发送报头的长度
    conn.send(struct.pack("i", len(header_bytes)))

    # 第三步:再发报头
    conn.send(header_bytes)

    # 第四步:再发送真实的数据
    with open("%s/%s" % (share_dir, filename), "rb")as f:
        # conn.send(f.read())   # 如果文件太大,会占满内存
        for line in f:
            conn.send(line)


def put(conn, cmds):
    pass


def run():
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # (如果机器中存在,重新用端口)应对端口占用报错情况
    phone.bind(("127.0.0.1", 9909))   # 127.0.0.1本地地址,端口范围0-65535:其中0-1024给操作系统使用
    phone.listen(5)   # 5代表最大挂起连接数

    print("starting...")
    while True:  # 循环链接
        conn, client = phone.accept()  # conn套接字对象

        while True:    # 通讯循环
            try:
                # 1、接收命令  (命令:执行系统命令)
                res = conn.recv(8096)  # b‘get a.txt

                # 2、解析命令,提取相应的命令参数
                cmds = res.decode("utf-8").split()
                if cmds[0] == "get":
                    get(conn, cmds)
                elif cmds[0] == "put":
                    put(conn, cmds)
            except ConnectionRefusedError:
                break

        conn.close()

    phone.close()


if __name__ == "__main__":   #如果是执行当前文件的时候,这个条件成立,就执行。如果当前文件被其他文件当成模块导入的时候,这个条件是不成立的,里面的代码是不执行的
    run()

 客户端

import socket
import struct
import json

download_dir = r"F:\project\book\chapter6\文件传输\函数版本\client\download"


def get(phone, cmds):
    # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户端的新文件中
    # 第一步:先收报头的长度
    header = phone.recv(4)
    header_size = struct.unpack("i", header)[0]

    # 第二步:再接收报头信息
    header_bytes = phone.recv(header_size)

    # 第三步:从报头中解析出对真实数据的描述信息
    header_json = header_bytes.decode("utf-8")
    header_dic = json.loads(header_json)
    print(header_dic)
    file_size = header_dic["file_size"]
    filename = header_dic["filename"]

    # 第四步:接受真实的数据
    with open("%s/%s" % (download_dir, filename), "wb")as f:
        recv_size = 0
        while recv_size < file_size:
            line = phone.recv(1024)
            f.write(line)
            recv_size += len(line)
            print("总大小:%s  已下载大小:%s" % (file_size, recv_size))


def put(phone, cmds):
    pass


def run():
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    phone.connect(("127.0.0.1", 9909))  # phone相当于服务端的conn

    while True:
        # 1、发命令
        inp = input(">> ").strip()  # get a.txt
        if not inp:
            continue
        phone.send(inp.encode("utf-8"))
        cmds = inp.split()  # ["get","a.txt"]
        if cmds[0] == "get":
            get(phone, cmds)
        elif cmds[0] == "put":
            put(phone, cmds)
    phone.close()


if __name__ == "__main__":   # 如果是执行当前文件的时候,这个条件成立,就执行。如果当前文件被其他文件当成模块导入的时候,这个条件是不成立的,里面的代码是不执行的
    run()

  

 

文件传送

标签:error   [1]   python   ref   传输   情况   导入   对象   split   

原文地址:https://www.cnblogs.com/fantsaymwq/p/10051282.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!