zoukankan      html  css  js  c++  java
  • 17 [网络编程]-文件传输

    1.通过socket收发文件软件开发

    1、客户端提交命令
    
    2、服务端接收命令,解析,执行下载文件的方法,即以读的方式打开文件,for循环读出文件的一行行内容,然后send给客户端
    
    3、客户端以写的方式打开文件,将接收的内容写入文件中
    

      

    2、文件传输普通版

      (1)服务端

    import socket
    import struct
    import subprocess
    import json
    import os
    
    
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server.bind(('127.0.0.1', 9994))
    
    server.listen(5)
    
    while True:
        print('waiting...')
        conn, addr = server.accept()
    
        while True:
            try:
                cmds = conn.recv(1024)   # get a.txt
                print('=》', cmds)
                if not cmds:
                    break
    
                # 提取出相应的命令参数
    
                filename = cmds.decode('utf-8').split()[1]
                print(filename)
                # 以读的方式打开文件,将数据一点点发送给客户端
    
                # 第一步:制作报头
                header_dict = {
                    'filename': filename,
                    'md5': 'afdsafsaf',
                    'total_size': os.path.getsize(filename)
                }
                header_json = json.dumps(header_dict)  # 报头的json样式
                header_bytes = header_json.encode('utf-8')          # 报头---报头.json---报头.bytes
    
                # 发送报头的长度
                header_len = struct.pack('i', len(header_bytes))    # 报头bytes---> len()---> struct
                conn.send(header_len)
    
                # 第二部:把报头发送给客户端
                conn.send(header_bytes)
    
                # 第三部:发送真实数据
                with open(filename, 'rb') as f:
                    for line in f:
                        conn.send(line)
    
            except ConnectionResetError:
                break
    
        conn.close()
    
    
    server.close()

      (2)客户端

    import socket
    import struct
    import json
    
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    client.connect(('127.0.0.1', 9994))
    
    while True:
    
        data = input('>>>').strip()         # get a.txt
        if not data:
            continue
        client.send(data.encode('utf-8'))
    
        # 以写的方式,打开一个新文件,接受服务端传来的文件内容,写入新文件
    
        # 2.接受报头的长度
        header_bytes_len = client.recv(1024)
        header_bytes_len = struct.unpack('i', header_bytes_len)[0]
    
        # 接收报头的json数据
        header_bytes = client.recv(header_bytes_len)
        print(header_bytes)
    
        # 3.从报头中解析出对真实数据的描述信息(数据的长度)
        header_json = header_bytes.decode('utf-8')
        header_dict = json.loads(header_json)
    
        total_size = header_dict['total_size']
        filename = header_dict['filename']
        # 3.一段段的取数据
    
        # 4.打开文件,写入内容
    
        new_file = "%s.bak" % filename
        with open(new_file, 'wb') as f:
            recv_size = 0
            while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
                data = client.recv(1024)
                f.write(data)
                recv_size += len(data)
    
    client.close()

    3、文件传输:拼接路径版本

       

    import socket
    import struct
    import subprocess
    import json
    import os
    
    
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server.bind(('127.0.0.1', 9994))
    
    server.listen(5)
    
    while True:
        print('waiting...')
        conn, addr = server.accept()
    
        while True:
            try:
                cmds = conn.recv(1024)   # get a.txt
                print('=》', cmds)
                if not cmds:
                    break
    
                # 提取出相应的命令参数
    
                filename = cmds.decode('utf-8').split()[1]   # 获取basename
                print(filename)
                # 绝对路径拼接
                SERVER_PATH = os.path.dirname(os.path.abspath(__file__))
                FILE_PATH = os.path.join(os.path.join(SERVER_PATH, 'share'), filename)
    
                # 以读的方式打开文件,将数据一点点发送给客户端
    
                # 第一步:制作报头
                header_dict = {
                    'filename': FILE_PATH,
                    'md5': 'afdsafsaf',
                    'total_size': os.path.getsize(FILE_PATH)
                }
                header_json = json.dumps(header_dict)  # 报头的json样式
                header_bytes = header_json.encode('utf-8')          # 报头---报头.json---报头.bytes
    
                # 发送报头的长度
                header_len = struct.pack('i', len(header_bytes))    # 报头bytes---> len()---> struct
                conn.send(header_len)
    
                # 第二部:把报头发送给客户端
                conn.send(header_bytes)
    
                # 第三部:发送真实数据
                with open(FILE_PATH, 'rb') as f:
                    for line in f:
                        conn.send(line)
    
            except ConnectionResetError:
                break
    
        conn.close()
    
    
    server.close()
    服务端
    import socket
    import os
    import struct
    import json
    
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    client.connect(('127.0.0.1', 9994))
    
    while True:
    
        data = input('>>>').strip()         # get a.txt
        if not data:
            continue
        client.send(data.encode('utf-8'))
    
        # 以写的方式,打开一个新文件,接受服务端传来的文件内容,写入新文件
    
        # 2.接受报头的长度
        header_bytes_len = client.recv(1024)
        header_bytes_len = struct.unpack('i', header_bytes_len)[0]
    
        # 接收报头的json数据
        header_bytes = client.recv(header_bytes_len)
    
        # 3.从报头中解析出对真实数据的描述信息(数据的长度)
        header_json = header_bytes.decode('utf-8')
        header_dict = json.loads(header_json)
    
        total_size = header_dict['total_size']
        filename = header_dict['filename']
        # 3.一段段的取数据
    
        # 4.打开文件,写入内容, 文件路径修改
        CLIENT_PATH = os.path.dirname(os.path.abspath(__file__))
        FILE_PATH = os.path.join(os.path.join(CLIENT_PATH, 'download'), os.path.basename(filename))
    
        with open(FILE_PATH, 'wb') as f:
            recv_size = 0
            while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
                data = client.recv(1024)  
                f.write(data)
                recv_size += len(data)
                print("总共%s bytes 已经传输%s bytes" %(total_size,recv_size))   # 简易进度条
    client.close()
    客户端

        

    •   pycharm 显示目录延迟!

    4、函数版本:上传,下载功能

      (1)服务端

    import socket
    import struct
    import subprocess
    import json
    import os
    
    
    def get(cmds, conn):
        filename = cmds.decode('utf-8').split()[1]  # 获取basename
    
        # 绝对路径拼接
        SERVER_PATH = os.path.dirname(os.path.abspath(__file__))
        FILE_PATH = os.path.join(os.path.join(SERVER_PATH, 'share'), filename)
    
        # 以读的方式打开文件,将数据一点点发送给客户端
    
        # 第一步:制作报头
        header_dict = {
            'filename': FILE_PATH,
            'md5': 'afdsafsaf',
            'total_size': os.path.getsize(FILE_PATH)
        }
        header_json = json.dumps(header_dict)  # 报头的json样式
        header_bytes = header_json.encode('utf-8')  # 报头---报头.json---报头.bytes
    
        # 发送报头的长度
        header_len = struct.pack('i', len(header_bytes))  # 报头bytes---> len()---> struct
        conn.send(header_len)
    
        # 第二部:把报头发送给客户端
        conn.send(header_bytes)
    
        # 第三部:发送真实数据
        with open(FILE_PATH, 'rb') as f:
            for line in f:
                conn.send(line)
    
    
    def put(client):
        # 2.接受报头的长度
        header_bytes_len = client.recv(1024)
        header_bytes_len = struct.unpack('i', header_bytes_len)[0]
    
        # 接收报头的json数据
        header_bytes = client.recv(header_bytes_len)
    
        # 3.从报头中解析出对真实数据的描述信息(数据的长度)
        header_json = header_bytes.decode('utf-8')
        header_dict = json.loads(header_json)
    
        total_size = header_dict['total_size']
        filename = header_dict['filename']
        # 3.一段段的取数据
    
        # 4.打开文件,写入内容, 文件路径修改
        CLIENT_PATH = os.path.dirname(os.path.abspath(__file__))
        FILE_PATH = os.path.join(os.path.join(CLIENT_PATH, 'share'), os.path.basename(filename))
    
        with open(FILE_PATH, 'wb') as f:
            recv_size = 0
            while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
                data = client.recv(1024)
                f.write(data)
                recv_size += len(data)
                print("总共%s bytes 已经传输%s bytes" % (total_size, recv_size))  # 简易进度条
    
    
    def main():
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind(('127.0.0.1', 9994))
        server.listen(5)
        while True:
            print('waiting...')
            conn, addr = server.accept()
            while True:
                try:
                    cmds = conn.recv(1024)   # get a.txt
                    print('=》', cmds)
                    if not cmds:
                        break
    
                    # 提取出相应的命令参数
                    cmd_type = cmds.decode('utf-8').split()[0]
                    if cmd_type == 'get':
                        get(cmds, conn)
    
                    elif cmd_type == 'put':
                        put(conn)
    
                except ConnectionResetError:
                    break
    
            conn.close()
    
    
        server.close()
    
    if __name__ == '__main__':
        main()

      

      (2)客户端

    import socket
    import os
    import struct
    import json
    
    
    def get(client):
        # 以写的方式,打开一个新文件,接受服务端传来的文件内容,写入新文件
    
        # 2.接受报头的长度
        header_bytes_len = client.recv(1024)
        header_bytes_len = struct.unpack('i', header_bytes_len)[0]
    
        # 接收报头的json数据
        header_bytes = client.recv(header_bytes_len)
    
        # 3.从报头中解析出对真实数据的描述信息(数据的长度)
        header_json = header_bytes.decode('utf-8')
        header_dict = json.loads(header_json)
    
        total_size = header_dict['total_size']
        filename = header_dict['filename']
        # 3.一段段的取数据
    
        # 4.打开文件,写入内容, 文件路径修改
        CLIENT_PATH = os.path.dirname(os.path.abspath(__file__))
        FILE_PATH = os.path.join(os.path.join(CLIENT_PATH, 'download'), os.path.basename(filename))
    
        with open(FILE_PATH, 'wb') as f:
            recv_size = 0
            while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
                data = client.recv(1024)
                f.write(data)
                recv_size += len(data)
                print("总共%s bytes 已经传输%s bytes" % (total_size, recv_size))  # 简易进度条
    
    
    def put(cmds,client):
    
        # 文件路径拼接
        filename = cmds.split()[1]  # 获取basename
        CLIENT_PATH = os.path.dirname(os.path.abspath(__file__))
        FILE_PATH = os.path.join(os.path.join(CLIENT_PATH, 'download'), filename)
        if not os.path.isfile(FILE_PATH):
            print('this file is not find')
            return
        # 1.找出file的绝对路径
    
        # 2.读取文件的size
        header_dict = {
            'filename': FILE_PATH,
            'md5': 'dffsaf',
            'total_size': os.path.getsize(FILE_PATH),
        }
    
        # 3.传输报头
        header_json = json.dumps(header_dict)
        header_bytes = header_json.encode('utf-8')
        header_len = struct.pack('i', len(header_bytes))
        client.send(header_len)
    
        client.send(header_bytes)
    
        # 4.打开文件读取内容,并传输
        with open(FILE_PATH, 'rb') as f:
            for line in f:
                client.send(line)
    
    
    
    def main():
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect(('127.0.0.1', 9994))
    
        while True:
            cmds = input('>>>').strip()
            if not cmds:
                continue
            client.send(cmds.encode('utf-8'))
    
            cmd_type = cmds.split()[0]
            if cmd_type == 'get':
                get(client)
    
            elif cmd_type == 'put':
                put(cmds,client)
    
        client.close()
    
    if __name__ == '__main__':
        main()

        

    5、面向对象,类:文件传输

    • 自己写的
    import socket
    import struct
    import subprocess
    import json
    import os
    
    
    class Server(object):
    
        def __init__(self,ip,port):
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.ip = ip
            self.port = port
    
        def run(self):
            self.bind()
            self.listen()
            while True:
                print('waiting...')
                conn, addr = self.accept()
                print(conn, addr)
                while True:
                    try:
                        cmds = self.recv(conn)
                        print('=》', cmds)
                        if not cmds:
                            break
    
                        self.get(cmds, conn)
    
                    except ConnectionResetError:
                        break
    
                conn.close()
    
            self.socket.close()
    
        def bind(self):
            self.socket.bind((self.ip, self.port))
    
        def listen(self,):
            self.socket.listen(5)
    
        def accept(self):
            conn, addr = self.socket.accept()
            return conn, addr
    
        def recv(self,conn):
            cmds = conn.recv(1024)
            return cmds
    
        def get(self,cmds, conn):
            filename = cmds.decode('utf-8').split()[1]
    
            SERVER_PATH = os.path.dirname(os.path.abspath(__file__))
            FILE_PATH = os.path.join(os.path.join(SERVER_PATH, 'share'), filename)
    
            header_dict = {
                'filename': FILE_PATH,
                'md5': 'afdsafsaf',
                'total_size': os.path.getsize(FILE_PATH)
            }
            header_json = json.dumps(header_dict)
            header_bytes = header_json.encode('utf-8')
    
            header_len = struct.pack('i', len(header_bytes))
            conn.send(header_len)
    
            conn.send(header_bytes)
    
            with open(FILE_PATH, 'rb') as f:
                for line in f:
                    conn.send(line)
    
    server = Server('127.0.0.1', 9994)
    server.run()
    服务端
    import socket
    import os
    import struct
    import json
    
    
    class Client(object):
    
        def __init__(self,ip,port):
            self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.ip = ip
            self.port = port
    
        def run(self):
            self.connect()
            while True:
                data = input('>>>').strip()
                if not data:
                    continue
                self.client.send(data.encode('utf-8'))
                self.get()
            self.client.close()
    
        def connect(self):
            self.client.connect((self.ip, self.port))
    
        def get(self):
            header_bytes_len = self.client.recv(1024)
            header_bytes_len = struct.unpack('i', header_bytes_len)[0]
            header_bytes = self.client.recv(header_bytes_len)
    
            header_json = header_bytes.decode('utf-8')
            header_dict = json.loads(header_json)
    
            total_size = header_dict['total_size']
            filename = header_dict['filename']
    
            CLIENT_PATH = os.path.dirname(os.path.abspath(__file__))
            FILE_PATH = os.path.join(os.path.join(CLIENT_PATH, 'download'), os.path.basename(filename))
    
            with open(FILE_PATH, 'wb') as f:
                recv_size = 0
                while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
                    data = self.client.recv(1024)
                    f.write(data)
                    recv_size += len(data)
                    print("总共%s bytes 已经传输%s bytes" % (total_size, recv_size))  # 简易进度条
    
    
    client = Client('127.0.0.1',9994)
    client.run()
    客户端
    • 老师写的
    import socket
    import struct
    import json
    import subprocess
    import os
    
    class MYTCPServer:
        address_family = socket.AF_INET
    
        socket_type = socket.SOCK_STREAM
    
        allow_reuse_address = False
    
        max_packet_size = 8192
    
        coding='utf-8'
    
        request_queue_size = 5
    
        server_dir='file_upload'
    
        def __init__(self, server_address, bind_and_activate=True):
            """Constructor.  May be extended, do not override."""
            self.server_address=server_address
            self.socket = socket.socket(self.address_family,
                                        self.socket_type)
            if bind_and_activate:
                try:
                    self.server_bind()
                    self.server_activate()
                except:
                    self.server_close()
                    raise
    
        def server_bind(self):
            """Called by constructor to bind the socket.
            """
            if self.allow_reuse_address:
                self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.socket.bind(self.server_address)
            self.server_address = self.socket.getsockname()
    
        def server_activate(self):
            """Called by constructor to activate the server.
            """
            self.socket.listen(self.request_queue_size)
    
        def server_close(self):
            """Called to clean-up the server.
            """
            self.socket.close()
    
        def get_request(self):
            """Get the request and client address from the socket.
            """
            return self.socket.accept()
    
        def close_request(self, request):
            """Called to clean up an individual request."""
            request.close()
    
        def run(self):
            while True:
                self.conn,self.client_addr=self.get_request()
                print('from client ',self.client_addr)
                while True:
                    try:
                        head_struct = self.conn.recv(4)
                        if not head_struct:break
    
                        head_len = struct.unpack('i', head_struct)[0]
                        head_json = self.conn.recv(head_len).decode(self.coding)
                        head_dic = json.loads(head_json)
    
                        print(head_dic)
                        #head_dic={'cmd':'put','filename':'a.txt','filesize':123123}
                        cmd=head_dic['cmd']
                        if hasattr(self,cmd):
                            func=getattr(self,cmd)
                            func(head_dic)
                    except Exception:
                        break
    
        def put(self,args):
            file_path=os.path.normpath(os.path.join(
                self.server_dir,
                args['filename']
            ))
    
            filesize=args['filesize']
            recv_size=0
            print('----->',file_path)
            with open(file_path,'wb') as f:
                while recv_size < filesize:
                    recv_data=self.conn.recv(self.max_packet_size)
                    f.write(recv_data)
                    recv_size+=len(recv_data)
                    print('recvsize:%s filesize:%s' %(recv_size,filesize))
    
    
    tcpserver1=MYTCPServer(('127.0.0.1',8080))
    
    tcpserver1.run()
    服务端实现
    import socket
    import struct
    import json
    import os
    
    
    
    class MYTCPClient:
        address_family = socket.AF_INET
    
        socket_type = socket.SOCK_STREAM
    
        allow_reuse_address = False
    
        max_packet_size = 8192
    
        coding='utf-8'
    
        request_queue_size = 5
    
        def __init__(self, server_address, connect=True):
            self.server_address=server_address
            self.socket = socket.socket(self.address_family,
                                        self.socket_type)
            if connect:
                try:
                    self.client_connect()
                except:
                    self.client_close()
                    raise
    
        def client_connect(self):
            self.socket.connect(self.server_address)
    
        def client_close(self):
            self.socket.close()
    
        def run(self):
            while True:
                inp=input(">>: ").strip()
                if not inp:continue
                l=inp.split()
                cmd=l[0]
                if hasattr(self,cmd):
                    func=getattr(self,cmd)
                    func(l)
    
    
        def put(self,args):
            cmd=args[0]
            filename=args[1]
            if not os.path.isfile(filename):
                print('file:%s is not exists' %filename)
                return
            else:
                filesize=os.path.getsize(filename)
    
            head_dic={'cmd':cmd,'filename':os.path.basename(filename),'filesize':filesize}
            print(head_dic)
            head_json=json.dumps(head_dic)
            head_json_bytes=bytes(head_json,encoding=self.coding)
    
            head_struct=struct.pack('i',len(head_json_bytes))
            self.socket.send(head_struct)
            self.socket.send(head_json_bytes)
            send_size=0
            with open(filename,'rb') as f:
                for line in f:
                    self.socket.send(line)
                    send_size+=len(line)
                    print(send_size)
                else:
                    print('upload successful')
    
    
    
    
    client=MYTCPClient(('127.0.0.1',8080))
    
    client.run()
    客户端实现
  • 相关阅读:
    数组删除元素注意事项
    点击下拉菜单以外的区域,关闭弹窗
    webpack学习笔记(六)优化
    webpack学习笔记(五)
    webpack学习笔记(四)
    webpack学习笔记(三)
    webpack学习笔记(二)
    es6 笔记
    vue学习笔记——组件的优化
    vue学习笔记——路由
  • 原文地址:https://www.cnblogs.com/venicid/p/8679516.html
Copyright © 2011-2022 走看看