文件上传和多线程通信

文件上传

  • 基于TCP的方法

    • client

      • import socket
        import os
        import json
        import struct
        FILE_PATH = os.path.join(os.path.dirname(__file__),"demo.mp4")
        
        def socket_client():
            client = socket.socket()
        
            client.connect(('127.0.0.1',8848))
        
            #制作字典形式的报头
        
            head_dic = {
                'md5': 13212314114141313,
                'file_name':os.path.basename(FILE_PATH),
                'file_size':os.path.getsize(FILE_PATH),
                'new_file_name':'demo_new.mp4'
            }
            #获取json形式的报头
            head_dic_json = json.dumps(head_dic)
        
            #获取bytes形式的报头
            head_dic_json_bytes = head_dic_json.encode('utf-8')
        
            #获取bytes报头的总字节数
            head_len = len(head_dic_json_bytes)
        
            #将报头的总字节数转化为固定的四个字节
            four_bytes = struct.pack('i',head_len)
        
            #发送四个固定字节的报头
            client.send(four_bytes)
        
            #发送字典的bytes报头
            client.send(head_dic_json_bytes)
        
            #发送总数据
            with open(FILE_PATH,mode = 'rb') as f1:
                while 1:
                    every_data = f1.read(1024)
                    if every_data:
                        client.send(every_data)
                    else:
                        break
            client.close()
        socket_client()
        
    • server

      • import socket
        import struct
        import json
        import os
        MY_FILE = os.path.join(os.path.dirname(__file__),'my_file')
        def socket_sever():
            sever = socket.socket()
        
            sever.bind(('127.0.0.1',8848))
        
            sever.listen(5)
        
            conn,addr = sever.accept()
        
            #接受固定长度的四个字节
            four_bytes = conn.recv(4)
        
            #利用struct反解
            head_len = struct.unpack('i',four_bytes)[0]
        
            #接受bytes类型的报头
            head_dic_json_bytes = conn.recv(head_len)
        
            #将bytes类型的报头转化成json
            head_dic_json = head_dic_json_bytes.decode('utf-8')
        
            #将json类型报头转化成字典形式的报头
            head_dic = json.loads(head_dic_json)
        
            #MD5校验
        
            #接受源数据
            with open(os.path.join(MY_FILE,head_dic["new_file_name"]),mode = 'wb') as f1:
                total_size =0
                every_data = ''
                while total_size < head_dic['file_size']:
                    every_data = conn.recv(1024)
                    f1.write(every_data)
                    total_size +=len(every_data)
            conn.close()
            sever.close()
        socket_sever()
        
      • 目录结构

        • QQ截图20190718150401

6基于UDP协议的socket通信

  • udp协议:不可靠,相对来说不安全的协议,面向数据(无连接)的协议,速度快,原因是tcp需要建立连接,当数据传输完成后输出缓存区的数据暂时不会消失,等待回调函数传回信息后,再清空输出缓存区的数据,如图

    • QQ截图20190718150847
  • socketserver

    • 从源码解读

    • QQ截图20190718151054

      QQ截图20190718151149

    • 代码如下:可实现多线程的通信

      • udp_server

      • import socketserver
        
        
        class MySever(socketserver.BaseRequestHandler):  # 继承的类固定
        
            def handle(self):  # 必须是handle名字
        
                while 1:
                    from_client_data = self.request.recv(1024).decode('utf-8')#self.request相当于conn通道
                    print(from_client_data)
                    to_client_data = input('>>>').strip()
                    self.request.send(to_client_data.encode('utf-8'))
        
        if __name__ == '__main__':
            ip_port = ('127.0.0.1',8848)
            sever = socketserver.ThreadingTCPServer(ip_port,MySever)#基于tcp协议的多线程服务端
            sever.serve_forever()
        
      • udp_client

      • import socket
        
        phone = socket.socket()
        
        phone.connect(('127.0.0.1',8848))
        
        while 1:
            to_sever = input(">>>").strip()
            phone.send(f"小米:{to_sever}".encode('utf-8'))
        
            from_server_data = phone.recv(1024)
            print(f"来自服务器的消息:{from_server_data.decode('utf-8')}")
        
原文地址:https://www.cnblogs.com/W-Y-C/p/11207545.html