• Python socket文件上传下载


    python网络编程

    程序的目录结构

    socketDemo
    ├── client
    │   ├── cli.py
    │   └── local_dir
    │       └── lianxijiangjie.mp4
    └── server
        ├── download
        │   └── lianxijiangjie.mp4
        └── ser.py

    基础版本

    ser.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = 'mosson'
    import socket
    import struct
    import json
    import os
    
    base_dir = os.path.dirname(os.path.abspath(__file__))
    base_dir = os.path.join(base_dir, 'download')
    
    
    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):
            print('server is running .......')
            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)
                        cmd=head_dic['cmd']
                        if hasattr(self,cmd):
                            func=getattr(self,cmd)
                            func(head_dic)
                    except Exception:
                        break
    
        def put(self,args):
            """
            文件长传
            :param args:
            :return:
            """
            file_path=os.path.normpath(os.path.join(
                base_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(2048)
                    f.write(recv_data)
                    recv_size += len(recv_data)
                else:
                    print('recvsize:%s filesize:%s' %(recv_size,filesize))
    
        def get(self, args):
            """ 下载文件
            1 检测服务端文件是不是存在
            2 文件信息 打包发到客户端
            3 发送文件
            """
            filename = args['filename']
            dic = {}
            if os.path.isfile(base_dir + '/' + filename):
                dic['filesize'] = os.path.getsize(base_dir + '/' + filename)
                dic['isfile'] = True
            else:
                dic['isfile'] = False
            str_dic = json.dumps(dic) # 字典转str
            bdic = str_dic.encode(self.coding) # str转bytes
            dic_len = len(bdic) # 计算bytes的长度
            bytes_len = struct.pack('i', dic_len) # 
            self.conn.send(bytes_len) # 发送长度
            self.conn.send(bdic)  # 发送字典
            # 文件存在发送真实文件
            if dic['isfile']:
                with open(base_dir + '/' + filename, 'rb') as f:
                    while dic['filesize'] > 2048:
                        content = f.read(2048)
                        self.conn.send(content)
                        dic['filesize'] -= len(content)
                    else:
                        content = f.read(2048)
                        self.conn.send(content)
                        dic['filesize'] -= len(content)
                print('下载完成')
    
    
    tcpserver1=MYTCPServer(('127.0.0.1',8083))
    
    tcpserver1.run()
    服务端代码

    cli.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = 'mosson'
    
    import socket
    import struct
    import json
    import os
    import time
    
    base_dir = os.path.dirname(os.path.abspath(__file__))
    base_dir = os.path.join(base_dir, 'local_dir')
    
    
    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]
            filename = base_dir + '/' + filename
            print(filename)
            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
            t1 = time.time()
            # with open(filename,'rb') as f:
            #     for line in f:
            #         self.socket.send(line)
            #         send_size+=len(line)
            #     else:
            #         print('upload successful')
            #         t2 = time.time()
            with open(filename, 'rb') as f:
                while head_dic['filesize'] > 2048:
                    content = f.read(2048)
                    self.socket.send(content)
                    head_dic['filesize'] -= len(content)
                else:
                    content = f.read(2048)
                    self.socket.send(content)
                    head_dic['filesize'] -= len(content)
                t2 = time.time()
    
                
    
            
            print(t2-t1)
    
        def get(self, args):
            cmd = args[0]
            filename = args[1]
            dic = {'cmd': cmd, 'filename': filename}
            """发送dic的步骤
            字典转str
            str转bytes
            计算bytes的长度
            发送长度
            发送字典
            """
            str_dic = json.dumps(dic) # 字典转str
            bdic = str_dic.encode(self.coding) # str转bytes
            dic_len = len(bdic) # 计算bytes的长度
            bytes_len = struct.pack('i', dic_len) # 
            self.socket.send(bytes_len) # 发送长度
            self.socket.send(bdic)  # 发送字典
    
            # 接受 准备下载的文件信息
            dic_len = self.socket.recv(4)
            dic_len = struct.unpack('i', dic_len)[0]
            dic = self.socket.recv(dic_len).decode(self.coding)
            dic = json.loads(dic)
            # 文件存在准备下载
            if dic['isfile']:
                t1 = time.time()
                with open(base_dir+'/'+filename, 'wb') as f:
                    while dic['filesize'] > 2048:
                        content = self.socket.recv(2048)
                        f.write(content)
                        dic['filesize'] -= len(content)
                    else:
                        while dic['filesize']:
                            content = self.socket.recv(2048)
                            f.write(content)
                            dic['filesize'] -= len(content)
                        t2 = time.time()
                print(t2-t1)
    
            else:
                print('文件不存在!')
    
    
    
    
    client=MYTCPClient(('127.0.0.1',8083))
    
    client.run()
    客户端代码

    升级版本

    。。。。。。。。

    ==================== 码字不易,如有帮助,请多多支持 ====================

     

  • 相关阅读:
    关于document.referrer的使用需要注意
    Vue2.0表单校验组件vee-validate的使用
    Ubuntu 20.04 Docker 安装并配置
    换硬盘,装win10系统小记
    关于MongoDB ObjectId的那些事儿
    水平垂直居中常见解决方案
    JSON基础知识总结
    css选择器中:first-child与:first-of-type的区别
    基于jQuery选择器的整理集合
    DOM对象与jquery对象有什么不同
  • 原文地址:https://www.cnblogs.com/mosson/p/11098202.html
Copyright © 2020-2023  润新知