1、基于tcp协议传送文件:
客户端:
import socketimport osimport jsonimport structclient = socket.socket()client.connect((‘127.0.0.1‘,8080)) # 文件大小file_size = os.path.getsize(r‘F:\老男孩Python7期\day32\视频\02TCP发送大文件.mp4‘) # 文件名字file_name = ‘TCP发送大文件.mp4‘# 定义一个字典d = { ‘file_name‘:file_name, ‘file_size‘:file_size}data_pytes = json.dumps(d).encode(‘utf-8‘)# 制作报头header = struct.pack(‘i‘,len(data_pytes))# 发送报文client.send(header)# 发送字典client.send(data_pytes)# 发送真实数据with open(r‘F:\老男孩Python7期\day32\视频\02TCP发送大文件.mp4‘,‘rb‘) as f: for lie in f: client.send(lie) 服务端:
import socketimport structimport jsonimport os server = socket.socket()server.bind((‘127.0.0.1‘,8080))server.listen(5) while True: conn,addr = server.accept() while True: try: # 接收报头 header = conn.recv(4) # 解析报头,获取长度 header_len = struct.unpack(‘i‘,header)[0] print(‘长度为‘+header_len) # 接收字典,其中header_len显示为接收内容的长度 header_bytes = conn.recv(header_len) header_dic = json.loads(header_bytes.decode(‘utf-8‘)) print(header_dic) # 根据字典中的key获取对应的value file_name = header_dic[‘file_name‘] file_size = header_dic[‘file_size‘] resc_size = 0 # 文件操作 with open(file_name,‘wb‘) as f: while resc_size <file_size: data = conn.recv(1024) f.write(data) resc_size += len(data) except ConnectionRefusedError: break conn.close() 2、UDP协议通信(由于没有双通道,不会出现沾包、客户端中断或者服务端中断不影响、客户端可以发空内容) 客户端:
import socket client = socket.socket(type=socket.SOCK_DGRAM)service_addr =(‘127.0.0.1‘,8080)while True: msg = input(‘输入要发送的消息:‘) msg = ‘客户发送的消息:%s‘ % msg client.sendto(msg.encode(‘utf-8‘),service_addr) data,addr = client.recvfrom(1024) print(data.decode(‘utf-8‘)) print(addr)
服务端:
import socket service = socket.socket(type=socket.SOCK_DGRAM)service.bind((‘127.0.0.1‘,8080))while True: msg,addr = service.recvfrom(1024) print(msg.decode(‘utf-8‘)) print(addr) data = input(‘请输入回复消息:‘).encode(‘utf-8‘) service.sendto(data,addr) 基于sockerServer模块下tcp和udp高并发通讯 这里的高并发并不是真正意义上的高并发,是看起来像是同时运行的就成为并发# 注意事项:udp在测试高并发的时候不要默认循环测试,最好使用客户端使用一些io操作,不然会出现卡死现象 1、基于tcp的sockerServer模块使用 客户端:
import socket client = socket.socket()client.connect((‘127.0.0.1‘,8080))while True: msg = input(‘请输入要发送的消息:‘).encode(‘utf-8‘) client.send(msg) data = client.recv(1024) print(data.decode(‘utf-8‘))服务端:
import socketserverclass Mybaby(socketserver.BaseRequestHandler): def handle(self): while True: data = self.request.recv(1024) print(data.decode(‘utf-8‘)) msg = input(‘请输入要发送的消息:‘).encode(‘utf-8‘) self.request.send(msg)if __name__ == ‘__main__‘: server = socketserver.ThreadingTCPServer((‘127.0.0.1‘,8080),Mybaby) server.serve_forever() 2、基于UDP通信客户端:
import socketimport timeclient = socket.socket(type=socket.SOCK_DGRAM)service_addr = (‘127.0.0.1‘, 8080)while True: client.sendto(b‘hello world‘,service_addr) data, addr = client.recvfrom(1024) print(data) print(addr) time.sleep(2)服务端:
import socketserver class MyBaby(socketserver.BaseRequestHandler): def handle(self): while True: data,sock = self.request print(data) print(self.client_address) sock.sendto(data,self.client_address)if __name__ == ‘__main__‘: server = socketserver.ThreadingUDPServer((‘127.0.0.1‘,8080),MyBaby) server.serve_forever()
总结: 1、为什么会出现粘包现象? 只有在tcp协议中才会出现粘包现象,因为tcp协议是流式协议 特点是将数据量比较小且间隔时间短的数据一次性打包发送出去,本质还是因为我们不知道需要接收数据的长短。2、怎么解决粘包? 1、发送数据先告诉对方数据量的大小 2、利用struct模块定制自己的消息传输协议UDP协议: 1、udp协议客户端允许发空内容。 2、udp协议不会出现粘包。 3、udp协议服务端不存在的情况下,客户端照样不会报错。 4、udp协议支持并发。udp协议叫数据协议,发消息接收消息都带有报头upd的service不需要监听也不需要建立连接在启动服务后只能被动的等待客户端发送消息过来,客户端发送消息过来的时候,带上服务端的地址,服务端回复消息的时候,也到带上客户端的地址。
并发编程:多道技术的产生: 解决cpu在执行程序,遇到io时,cpu不干活的情况 串行:一个程序完完整整的运行完毕,才能运行下一个程序。 并发:看上去像是同时运行。多道技术: 空间上的复用(多个程序共用一套硬件设别,它是多道技术实现时间上的复用的基础。) 时间上的复用(单个cpu的电脑上,起多个应用程序,cpu快速切换,给人的感觉是同时运行) 一个任务占用cpu时间过长或被操作系统强行剥夺走cpu的执行权限(比起串行效率而降低) 一个任务执行过程中遇到io操作(等待时间),也会被操作系统强行剥夺cpu的执行权限(比串行效率高)
原文地址:https://www.cnblogs.com/yangzhaon/p/10815606.html
时间: 2024-08-22 04:27:45