文件上传和多线程通信
文件上传
-
基于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()
-
目录结构
-
-
6基于UDP协议的socket通信
-
udp协议:不可靠,相对来说不安全的协议,面向数据(无连接)的协议,速度快,原因是tcp需要建立连接,当数据传输完成后输出缓存区的数据暂时不会消失,等待回调函数传回信息后,再清空输出缓存区的数据,如图
-
socketserver
-
从源码解读
-
代码如下:可实现多线程的通信
-
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')}")
-
-