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

    传输文件简单版

    server端:

    import socket
    import struct
    import json
    import os
    
    share_dir = r'C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本servershare'
    IP_PORT = ('127.0.0.1', 8999)
    
    def bytes2human(n):
        symbols = ('K', 'M', 'G', 'T', 'P', 'E')
        prefix = {}
        for i, s in enumerate(symbols):
            # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
            # 10位就表示1024 即1 << 10=1024 就是2的n次方
            prefix[s] = 1 << (i + 1) * 10
        for s in reversed(symbols):
            if n >= prefix[s]:
                value = float(n) / prefix[s]
                return '%.2f%s' % (value, s)
        return "%sB" % n
    
    def get(conn,file_name):
        # 3、以读的方式打开文件,读取文件内容发送给客户端
        # 第一步:制作固定长度的报头
        print('get')
        try:
            header_dict = {
                'file_name': file_name,
                'md5': 'xxx',
                'file_size': os.path.getsize(os.path.join(share_dir, file_name))
    
            }
    
            header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
            header_bytes = header_json.encode('utf-8')
            # 第二步:先发送报头的长度
            conn.send(struct.pack('i', len(header_bytes)))
    
            # 第三步:再发报头
            conn.send(header_bytes)
    
            # 第四步:再发送真实的数据
            with open(os.path.join(share_dir, file_name), 'rb') as f:
                for line in f:
                    conn.send(line)
    
        except Exception as e:
            print(e)
    
    
    def put(conn, file_name):
        """
         接收客户端上传文件
        :param conn:
        :param file_name:
        :return:
        """
        # 2、以写的方式打开一个新文件,接收客户端发来的文件的内容写入服务端新文件
        # 第一步:先收报头的长度
        header_len = conn.recv(4)
        header_size = struct.unpack('i', header_len)[0]
    
        # 第二步:再收报头
        header_json = conn.recv(header_size).decode('utf-8')
    
        # 第三步:从报头中解析出对真实数据的描述信息
        header_dict = json.loads(header_json)
        file_size = header_dict['file_size']
        file_name = header_dict['file_name']
    
        print(os.path.join(share_dir, file_name))
        # 第四步:接收真实的数据,写入文件
        with open(os.path.join(share_dir, file_name), 'wb') as f:
            recv_size = 0
            while recv_size < file_size:
                line = conn.recv(1024)
                f.write(line)
                recv_size += len(line)
                print('总大小:%s   已上传大小:%s' % (bytes2human(file_size), bytes2human(recv_size)))
    
    
    def run():
        server = socket.socket(socket.AF_INET,  socket.SOCK_STREAM)
        server.bind(IP_PORT)
    
        server.listen(5)
        print('starting...')
    
        while True:
    
            conn, addr = server.accept()
            print(addr)
    
            while True:
                try:
                    # 1 收命令
                    res = conn.recv(1024)  # b' get a.txt'
                    if not res:break
                    # 2、解析命令,提取相应命令参数
                    cmds = res.decode('utf-8').split()  # [get, a.txt]
                    if cmds[0] == 'get':
                        get(conn, cmds[1])  # 下载文件
                        # file_name = cmds[1]
                    elif cmds[0] == 'put':
                        put(conn, cmds[1])  # 上传文件
                except ConnectionResetError: #适用于windows操作系统
                    break
            conn.close()
    
        server.close()
    
    
    if __name__ == '__main__':
        run()
    

      

    client端

      

    #!/usr/bin/env python3 
    # -*- coding: utf-8 -*-
    
    
    import socket
    import struct
    import json
    import os
    
    share_dir = r'C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本clientdownload'
    IP_PORT = ('127.0.0.1', 8999)
    
    
    def bytes2human(n):
        symbols = ('K', 'M', 'G', 'T', 'P', 'E')
        prefix = {}
        for i, s in enumerate(symbols):
            # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
            # 10位就表示1024 即1 << 10=1024 就是2的n次方
            prefix[s] = 1 << (i + 1) * 10
        for s in reversed(symbols):
            if n >= prefix[s]:
                value = float(n) / prefix[s]
                return '%.2f%s' % (value, s)
        return "%sB" % n
    
    
    def get(client, file_name):
        # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户的新文件
        # 第一步:先收报头的长度
        header_len = client.recv(4)
        header_size = struct.unpack('i', header_len)[0]
    
        # 第二步:再收报头
        header_json = client.recv(header_size).decode('utf-8')
    
        # 第三步:从报头中解析出对真实数据的描述信息
        header_dict = json.loads(header_json)
        file_size = header_dict['file_size']
        file_name = header_dict['file_name']
    
        print(os.path.join(share_dir, file_name))
        # 第四步:接收真实的数据,写入文件
        with open(os.path.join(share_dir, file_name), 'wb') as f:
            recv_size = 0
            while recv_size < file_size:
                line = client.recv(1024)
                f.write(line)
                recv_size += len(line)
                print('总大小:%s   已下载大小:%s' % (bytes2human(file_size), bytes2human(recv_size)))
    
    
    def put(client, file_name):
        # 向服务端上传文件
        print('put')
        try:
            if not os.path.isfile(os.path.join(share_dir, file_name)):
                print('file:%s is not exists' % os.path.join(share_dir, file_name))
                return
            else:
                file_size = os.path.getsize(os.path.join(share_dir, file_name))
                header_dict = {
                    'file_name': file_name,
                    'md5': 'xxx',
                    'file_size': file_size
    
                }
    
                header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
                header_bytes = header_json.encode('utf-8')
                # 第二步:先发送报头的长度
                client.send(struct.pack('i', len(header_bytes)))
    
                # 第三步:再发报头
                client.send(header_bytes)
    
                # 第四步:再发送真实的数据
                with open(os.path.join(share_dir, file_name), 'rb') as f:
                    for line in f:
                        client.send(line)
    
        except Exception as e:
            print(e)
    
    
    def run():
        client = socket.socket(socket.AF_INET,  socket.SOCK_STREAM)
        client.connect(IP_PORT)
    
        while True:
            # 1、发命令
            cmd = input('>> ').strip()  # 'get a.txt'
            if not cmd:continue
            client.send(cmd.encode('utf-8'))
    
            if cmd.startswith('get'):
                get(client, cmd.split()[1])
            elif cmd.startswith('put'):
                put(client, cmd.split()[1])
    
        client.close()
    
    
    if __name__ == '__main__':
        run()
    

     

    输出结果

    sever:
    starting...
    ('127.0.0.1', 19074)
    get
    get
    C:UsersjingjingPycharmProjectspy3Project路飞第三模块第二章网络编程5_文件传输简单版本servershare3.jpeg
    总大小:75.36K   已上传大小:1.00K
    总大小:75.36K   已上传大小:2.00K
    ……
    总大小:75.36K   已上传大小:75.36K
    
    
    client:
    
    
    >> get 1.pptx
    C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本clientdownload1.pptx
    总大小:970.93K   已下载大小:1.00K
    总大小:970.93K   已下载大小:2.00K
    ……
    总大小:970.93K   已下载大小:970.93K
    >> put 3.jpeg
    put
    >> 
    

      

    传输文件优化版

    server端:

    import socket
    import struct
    import json
    import os
    
    
    class TCPServer:
    
        IP_PORT = ('127.0.0.1', 8999)
        request_queue_size = 5
        allow_reuse_address = False
        max_packet_size = 8192
    
        share_dir = r'C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本servershare'
    
        def __init__(self, address=IP_PORT, bind_and_activate=True):
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            if bind_and_activate:
                try:
                    self.server.bind(address)
                    self.server.listen(self.request_queue_size)
                    print('starting...')
    
                except Exception as e:
                    self.server.close()
                    raise e
    
        def get_request(self):
            """Get the request and client address from the socket.
            """
            return self.server.accept()
    
        def run(self):
            while True:
                self.conn, self.client_addr = self.get_request()
                print('from client ', self.client_addr)
                while True:
                    try:
                        # 1 收命令
                        res = self.conn.recv(self.max_packet_size)  # b' get a.txt'
                        if not res: break
                        # 2、解析命令,提取相应命令参数
                        cmds = res.decode('utf-8').split()  # [get, a.txt]
                        if hasattr(self, cmds[0]):
                            func = getattr(self, cmds[0])
                            func(cmds[1])
                    except ConnectionResetError:  # 适用于windows操作系统
                        break
                self.conn.close()
    
            self.server.close()
    
        def put(self, file_name):
            """
             接收客户端上传文件
            :param conn:
            :param file_name:
            :return:
            """
            print('get file %s' % file_name)
    
            # 2、以写的方式打开一个新文件,接收客户端发来的文件的内容写入服务端新文件
            # 第一步:先收报头的长度
            header_len = self.conn.recv(4)
            header_size = struct.unpack('i', header_len)[0]
    
            # 第二步:再收报头
            header_json = self.conn.recv(header_size).decode('utf-8')
    
            # 第三步:从报头中解析出对真实数据的描述信息
            header_dict = json.loads(header_json)
            file_size = header_dict['file_size']
            file_name = header_dict['file_name']
    
            print(os.path.join(self.share_dir, file_name))
            # 第四步:接收真实的数据,写入文件
            with open(os.path.join(self.share_dir, file_name), 'wb') as f:
                recv_size = 0
                while recv_size < file_size:
                    line = self.conn.recv(self.max_packet_size)
                    f.write(line)
                    recv_size += len(line)
                    rate = recv_size / file_size * 100
                    print('总大小:%s   已上传:%%%.2f' % (self.bytes2human(file_size), rate))
    
        @staticmethod
        def bytes2human(n):
            symbols = ('K', 'M', 'G', 'T', 'P', 'E')
            prefix = {}
            for i, s in enumerate(symbols):
                # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
                # 10位就表示1024 即1 << 10=1024 就是2的n次方
                prefix[s] = 1 << (i + 1) * 10
            for s in reversed(symbols):
                if n >= prefix[s]:
                    value = float(n) / prefix[s]
                    return '%.2f%s' % (value, s)
            return "%sB" % n
    
        def get(self, file_name):
            # 3、以读的方式打开文件,读取文件内容发送给客户端
            # 第一步:制作固定长度的报头
            print('send file %s' % file_name)
            try:
                header_dict = {
                    'file_name': file_name,
                    'md5': 'xxx',
                    'file_size': os.path.getsize(os.path.join(self.share_dir, file_name))
    
                }
    
                header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
                header_bytes = header_json.encode('utf-8')
                # 第二步:先发送报头的长度
                self.conn.send(struct.pack('i', len(header_bytes)))
    
                # 第三步:再发报头
                self.conn.send(header_bytes)
    
                # 第四步:再发送真实的数据
                with open(os.path.join(self.share_dir, file_name), 'rb') as f:
                    for line in f:
                        self.conn.send(line)
    
            except Exception as e:
                print(e)
    
    
    if __name__ == '__main__':
        s = TCPServer()
        s.run()
    

      

    client端:

    import socket
    import struct
    import json
    import os
    
    
    class TCPClient:
    
        IP_PORT = ('127.0.0.1', 8999)
        request_queue_size = 5
        allow_reuse_address = False
        max_packet_size = 8192
        share_dir = r'C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本clientdownload'
    
        def __init__(self, address=IP_PORT, connect=True):
            self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            if connect:
                try:
                    self.client.connect(address)
                except Exception as e:
                    self.client.close()
                    raise e
    
        def run(self):
            while True:
                # 1、发命令
                inp = input('>> ').strip()  # 'get a.txt'
                if not inp: continue
                self.client.send(inp.encode('utf-8'))
                cmd = inp.split()
                
                if hasattr(self, cmd[0]):
                    func = getattr(self, cmd[0])
                    func(cmd[1])
    
            client.close()
    
        @staticmethod
        def bytes2human(n):
            symbols = ('K', 'M', 'G', 'T', 'P', 'E')
            prefix = {}
            for i, s in enumerate(symbols):
                # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
                # 10位就表示1024 即1 << 10=1024 就是2的n次方
                prefix[s] = 1 << (i + 1) * 10
            for s in reversed(symbols):
                if n >= prefix[s]:
                    value = float(n) / prefix[s]
                    return '%.2f%s' % (value, s)
            return "%sB" % n
    
        def get(self, file_name):
            # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户的新文件
            # 第一步:先收报头的长度
            header_len = self.client.recv(4)
            header_size = struct.unpack('i', header_len)[0]
    
            # 第二步:再收报头
            header_json = self.client.recv(header_size).decode('utf-8')
    
            # 第三步:从报头中解析出对真实数据的描述信息
            header_dict = json.loads(header_json)
            file_size = header_dict['file_size']
            file_name = header_dict['file_name']
    
            print(os.path.join(self.share_dir, file_name))
            # 第四步:接收真实的数据,写入文件
            with open(os.path.join(self.share_dir, file_name), 'wb') as f:
                recv_size = 0
                while recv_size < file_size:
                    line = self.client.recv(self.max_packet_size)
                    f.write(line)
                    recv_size += len(line)
                    rate = recv_size / file_size * 100
                    print('总大小:%s   已下载:%%%.2f' % (self.bytes2human(file_size),rate))
    
        def put(self, file_name):
            # 向服务端上传文件
            print('put')
            try:
                if not os.path.isfile(os.path.join(self.share_dir, file_name)):
                    print('file:%s is not exists' % os.path.join(self.share_dir, file_name))
                    return
                else:
                    file_size = os.path.getsize(os.path.join(self.share_dir, file_name))
                    header_dict = {
                        'file_name': file_name,
                        'md5': 'xxx',
                        'file_size': file_size
        
                    }
        
                    header_json = json.dumps(header_dict, ensure_ascii='False', indent=2)
                    header_bytes = header_json.encode('utf-8')
                    # 第二步:先发送报头的长度
                    self.client.send(struct.pack('i', len(header_bytes)))
        
                    # 第三步:再发报头
                    self.client.send(header_bytes)
        
                    # 第四步:再发送真实的数据
                    with open(os.path.join(self.share_dir, file_name), 'rb') as f:
                        for line in f:
                            self.client.send(line)
        
            except Exception as e:
                print(e)
    
    
    if __name__ == '__main__':
        c = TCPClient()
        c.run()
    

      

    输出结果:

     

    sever:
    starting...
    from client  ('127.0.0.1', 3500)
    send file 3.jpeg
    get file 1.pptx
    C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本servershare1.pptx
    总大小:970.93K   已上传:%0.82
    ……
    总大小:970.93K   已上传:%99.96
    总大小:970.93K   已上传:%100.00
    
    
    client:
     C:/py3Project/路飞/第三模块/第二章网络编程/05_文件传输/简单版本/client/file_client.py
    >> get 3.jpeg
    C:py3Project路飞第三模块第二章网络编程5_文件传输简单版本clientdownload3.jpeg
    总大小:75.36K   已下载:%10.62
    ……
    总大小:75.36K   已下载:%99.49
    总大小:75.36K   已下载:%100.00
    >> put 1.pptx
    put
    >> 
    

      

      

  • 相关阅读:
    ARM Security Technology
    《Linux/UNIX系统编程手册》第6章 进程
    Go 数组合并去重和排序
    Elasticsearch 删除数据
    Go常用排序算法
    Exception in window.onload: An error has occuredJSPlugin.3005
    基于Flask的 api(四)
    基于Flask的 api(三)
    判断json对象时JSONArray还是JSONObject
    基于Flask的 api(二)
  • 原文地址:https://www.cnblogs.com/xiao-apple36/p/9286610.html
Copyright © 2011-2022 走看看