一.大文件的上传下载
server端
1 import socket 2 import os 3 import json 4 import struct 5 6 server = socket.socket() 7 server.bind(('127.0.0.1',8080)) 8 server.listen() 9 10 while True: 11 conn,addr = server.accept() 12 while True: 13 try: 14 header_len = conn.recv(4) 15 # 解析字典报头 16 header_len = struct.unpack('i',header_len)[0] 17 # 再接收字典数据 18 header_dic = conn.recv(header_len) 19 real_dic = json.loads(header_dic.decode('utf-8')) 20 # 获取数据长度 21 total_size = real_dic.get('file_size') 22 # 循环接收并写入文件 23 recv_size = 0 24 with open(real_dic.get('file_name'),'wb') as f: 25 while recv_size < total_size: 26 data = conn.recv(1024) 27 f.write(data) 28 recv_size += len(data) 29 print('上传成功') 30 except ConnectionResetError as e: 31 print(e) 32 break 33 conn.close()
client端
1 import socket 2 import json 3 import os 4 import struct 5 6 7 client = socket.socket() 8 client.connect(('127.0.0.1',8080)) 9 10 while True: 11 # 获取电影列表 循环展示 12 MOVIE_DIR = r'D:\python脱产10期视频\day25\视频' 13 movie_list = os.listdir(MOVIE_DIR) 14 # print(movie_list) 15 for i,movie in enumerate(movie_list,1): 16 print(i,movie) 17 # 用户选择 18 choice = input('please choice movie to upload>>>:') 19 # 判断是否是数字 20 if choice.isdigit(): 21 # 将字符串数字转为int 22 choice = int(choice) - 1 23 # 判断用户选择在不在列表范围内 24 if choice in range(0,len(movie_list)): 25 # 获取到用户想上传的文件路径 26 path = movie_list[choice] 27 # 拼接文件的绝对路径 28 file_path = os.path.join(MOVIE_DIR,path) 29 # 获取文件大小 30 file_size = os.path.getsize(file_path) 31 # 定义一个字典 32 res_d = { 33 'file_name':'性感荷官在线发牌.mp4', 34 'file_size':file_size, 35 'msg':'注意身体,多喝营养快线' 36 } 37 # 序列化字典 38 json_d = json.dumps(res_d) 39 json_bytes = json_d.encode('utf-8') 40 41 # 1.先制作字典格式的报头 42 header = struct.pack('i',len(json_bytes)) 43 # 2.发送字典的报头 44 client.send(header) 45 # 3.再发字典 46 client.send(json_bytes) 47 # 4.再发文件数据(打开文件循环发送) 48 with open(file_path,'rb') as f: 49 for line in f: 50 client.send(line) 51 else: 52 print('not in range') 53 else: 54 print('must be a number')
二.UDP通信
特点:1.数据宝协议(自带报头)
2.没有双向通道啊 通信类似于发短信
好处:1.udp协议客户端允许发空
2.udp协议不会粘包
3.udp协议服务端不存在的情况下,客户端照样不会报错
4.udp协议支持并发
UDP的基本使用
server端
1 import socket 2 3 4 server = socket.socket(type=socket.SOCK_DGRAM) # UDP协议 5 server.bind(('127.0.0.1',8080)) 6 # UDP不需要设置半连接池 它也没有半连接池的概念 7 8 # 因为没有双向通道 不需要accept 直接就是通信循环 9 while True: 10 data, addr = server.recvfrom(1024) 11 print('数据:',data) # 客户端发来的消息 12 print('地址:',addr) # 客户端的地址 13 server.sendto(data.upper(),addr)
client端
1 import socket 2 3 4 client = socket.socket(type=socket.SOCK_DGRAM) 5 # 不需要建立连接 直接进入通信循环 6 server_address = ('127.0.0.1',8080) 7 while True: 8 client.sendto(b'hello',server_address) 9 data, addr = client.recvfrom(1024) 10 print('服务端发来的数据',data) 11 print('服务端的地址',addr)
三.socketserver
1.用socketserver实现tcp
server端
1 import socketserver 2 3 4 class MyServer(socketserver.BaseRequestHandler): 5 def handle(self): 6 # print('来啦 老弟') 7 while True: 8 data = self.request.recv(1024) 9 print(self.client_address) # 客户端地址 10 print(data.decode('utf-8')) 11 self.request.send(data.upper()) 12 13 14 if __name__ == '__main__': 15 """只要有客户端连接 会自动交给自定义类中的handle方法去处理""" 16 server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer) # 创建一个基于TCP的对象 17 server.serve_forever() # 启动该服务对象
client端
1 import socket 2 3 client = socket.socket() 4 client.connect(('127.0.0.1',8080)) 5 6 while True: 7 client.send(b'hello') 8 data = client.recv(1024) 9 print(data.decode('utf-8'))
2.用socketserver实现udp
server端
1 import socketserver 2 3 4 class MyServer(socketserver.BaseRequestHandler): 5 def handle(self): 6 # print('来啦 老弟') 7 while True: 8 data,sock = self.request 9 print(self.client_address) # 客户端地址 10 print(data.decode('utf-8')) 11 sock.sendto(data.upper(),self.client_address) 12 13 14 if __name__ == '__main__': 15 """只要有客户端连接 会自动交给自定义类中的handle方法去处理""" 16 server = socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyServer) # 创建一个基于TCP的对象 17 server.serve_forever() # 启动该服务对象
client端
1 import socket 2 import time 3 4 client = socket.socket(type=socket.SOCK_DGRAM) 5 server_address = ('127.0.0.1',8080) 6 7 while True: 8 client.sendto(b'hello',server_address) 9 data,addr = client.recvfrom(1024) 10 print(data.decode('utf-8'),addr) 11 time.sleep(1)