zoukankan      html  css  js  c++  java
  • python socket文件传输实现

    简单版

    server(服务端)

    import socket
    import subprocess
    import struct
    import json
    import os
    
    share_dir = r'E:servershare'  # 需要传输的文件所在的文件夹
    
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 回收重用端口10000
    phone.bind(('127.0.0.1', 10000))  # 0-65535  0-1024给操作系统,
    phone.listen(5)
    print('stearting')
    while True:  # 建链接循环
        conn, client_addr = phone.accept()
        print(client_addr)
        while True:  # 通信循环
            try:
                # 1.收命令
                res = conn.recv(1024)  # get jiaoyue.mp4
                # 2.解析命令,提取相应命令参数
                cmds = res.decode('utf-8').split()  # ['get', 'jiaoyue.mp4']
                filename = cmds[1]
                # 3.以读的方式打开
    
                # 1制作报头
                header_dic = {
                    'filename': filename,
                    'md5': 'xxdxx',
                    'file_size': os.path.getsize(r'%s/%s' % (share_dir, filename)) #E:study第3模块,面向对象网络编程文件传输serversharejiaoyue.mp4
                }
                header_json = json.dumps(header_dic)
                header_bytes = header_json.encode('utf-8')
    
                # 2 发送报头长度
                conn.send(struct.pack('i', len(header_bytes)))  # 固定长度4
    
                # 3 发报头
                conn.send(header_bytes)
                # 4发真实数据
                with open('%s/%s' % (share_dir, filename), 'rb') as f:
                    # conn.send(f.read())
                    for a in f:
                        conn.send(a)
            except ConnectionResetError:
                break
        conn.close()
    phone.close()

    client(客户端)

    import socket
    import struct
    import json
    
    download_dir = r'E:clientdownload'  # 文件存放地址
    
    pc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    pc.connect(('127.0.0.1', 10000))
    
    while True:
        # 1.发命令
        cmd = input('>>>:').strip()  # get a.text
        if not cmd:
            continue
        pc.send(cmd.encode('utf-8'))
    
        # 2.接受文件内容,以写的方式打开一个新文件,写入客户端新文件中
    
        # 1收报头长度
        obj = pc.recv(4)
        header_size = struct.unpack('i', obj)[0]
    
        # 2接收报头
        header_bytes = pc.recv(header_size)
    
        # 3解析报头,对于数据的描述
        header_json = header_bytes.decode('utf-8')
        header_dic = json.loads(header_json)
        print(header_dic)
        total_size = header_dic['file_size']
        file_name = header_dic['filename']
    
        # 4 接受真实的数据
        with open('%s/%s' % (download_dir, file_name), 'wb') as f:
            recv_size = 0
            while recv_size < total_size:
                res = pc.recv(1024)
                f.write(res)
                recv_size += len(res)
                print('总大小:%s  已经下载大小:%s' % (total_size, recv_size))
    
    pc.close()

    优化之后的版本

    server

    import socket
    import struct
    import json
    import os
    
    
    share_dir = r'E:servershare'  # 文件地址
    
    def get(cmds, conn):
        filename = cmds[1]
        # 3.以读的方式打开,读取文件
        # 1制作报头
        header_dic = {
            'filename': filename,
            'md5': 'xxdxx',
            'file_size': os.path.getsize(r'%s/%s' % (share_dir, filename))  # E:study第3模块,面向对象网络编程文件传输serversharejiaoyue.mp4
        }
        header_json = json.dumps(header_dic)
        header_bytes = header_json.encode('utf-8')
    
        # 2 发送报头长度
        conn.send(struct.pack('i', len(header_bytes)))  # 固定长度4
    
        # 3 发报头
        conn.send(header_bytes)
        # 4发真实数据
        with open('%s/%s' % (share_dir, filename), 'rb') as f:
            # conn.send(f.read())
            for a in f:
                conn.send(a)
    
    def put(pc):
        # 2.接受文件内容,以写的方式打开一个新文件,写入客户端新文件中
        # 1收报头长度
        obj = pc.recv(4)
        header_size = struct.unpack('i', obj)[0]
    
        # 2接收报头
        header_bytes = pc.recv(header_size)
    
        # 3解析报头,对于数据的描述
        header_json = header_bytes.decode('utf-8')
        header_dic = json.loads(header_json)
        print(header_dic)
        total_size = header_dic['file_size']
        file_name = header_dic['filename']
    
        # 4 接受真实的数据
        with open('%s/%s' % (share_dir, file_name), 'wb') as f:
            recv_size = 0
            while recv_size < total_size:
                res = pc.recv(1024)
                f.write(res)
                recv_size += len(res)
                print('总大小:%s  已经下载大小:%s' % (total_size, recv_size))
    
    def run():
        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 回收重用端口10000
        phone.bind(('127.0.0.1', 10000))  # 0-65535  0-1024给操作系统,
        phone.listen(5)
        while True:  # 建链接循环
            conn, client_addr = phone.accept()
            print(client_addr)
            while True:  # 通信循环
                try:
                    # 1.收命令
                    res = conn.recv(1024)  # get jiaoyue.mp4
                    # 2.解析命令,提取相应命令参数
                    cmds = res.decode('utf-8').split()  # ['get', 'jiaoyue.mp4']
                    if cmds[0] == 'get':
                        get(cmds, conn)
                    elif cmds[0] == 'put':
                        put(conn)
                except ConnectionResetError:
                    break
            conn.close()
        phone.close()
    
    if __name__ == '__main__':
        run()

    client

    import socket
    import struct
    import json
    import os
    
    download_dir = r'E:clientdownload'  # 文件存放地址
    
    def get(pc):
        # 2.接受文件内容,以写的方式打开一个新文件,写入客户端新文件中
        # 1收报头长度
        obj = pc.recv(4)
        header_size = struct.unpack('i', obj)[0]
    
        # 2接收报头
        header_bytes = pc.recv(header_size)
    
        # 3解析报头,对于数据的描述
        header_json = header_bytes.decode('utf-8')
        header_dic = json.loads(header_json)
        print(header_dic)
        total_size = header_dic['file_size']
        file_name = header_dic['filename']
    
        # 4 接受真实的数据
        with open('%s/%s' % (download_dir, file_name), 'wb') as f:
            recv_size = 0
            while recv_size < total_size:
                res = pc.recv(1024)
                f.write(res)
                recv_size += len(res)
                print('总大小:%s  已经下载大小:%s' % (total_size, recv_size))
    
    def put(cmds, conn):
        filename = cmds[1]
        # 3.以读的方式打开,读取文件
        # 1制作报头
        header_dic = {
            'filename': filename,
            'md5': 'xxdxx',
            'file_size': os.path.getsize(r'%s/%s' % (download_dir, filename))
        }
        header_json = json.dumps(header_dic)
        header_bytes = header_json.encode('utf-8')
    
        # 2 发送报头长度
        conn.send(struct.pack('i', len(header_bytes)))  # 固定长度4
    
        # 3 发报头
        conn.send(header_bytes)
        # 4发真实数据
        send_size = 0
        with open('%s/%s' % (download_dir, filename), 'rb') as f:
            # conn.send(f.read())
            for a in f:
                conn.send(a)
                send_size += len(a)
                print(send_size)
    
    def run():
        pc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        pc.connect(('127.0.0.1', 10000))
        print(pc)
        while True:
            # 1.发命令
            inp = input('>>>:').strip()  # get a.text
            if not inp:
                continue
            pc.send(inp.encode('utf-8'))
            cmds = inp.split()
            if cmds[0] == 'get':
                get(pc)
            elif cmds[0] == 'put':
                put(cmds, pc)
        pc.close()
    
    if __name__ == '__main__':
        run()
  • 相关阅读:
    谷歌浏览器最新版下载链接
    第二章 算法——程序的灵魂
    第一章:程序设计和C语言
    C语言程序设计·谭浩强(第四版)第二章课后习题的答案,算法——程序的灵魂
    面向对象之类的其他方法
    面向对象之反射、包装、(定制)
    PyCharm使用秘籍视频
    re模块(详解正则)
    ATM购物车程序项目规范(更新到高级版)
    音乐脚本
  • 原文地址:https://www.cnblogs.com/Xanderzyl/p/10735247.html
Copyright © 2011-2022 走看看