标签:第二十八 struct header socket 字典 data size
socket套接字
基于TCP协议的socket
流式协议,面向流的通信是无消息保护边界的
会将数据少、时间间隔短的数据一次性打包发送
可靠但粘包:数据不会丢,包没收完,会继续上次继续接收数据。数据是可靠的
只有TCP有粘包现象
粘包问题
产生原因:1.发送的数据小,时间段,TCP会议会自动合成数据,造成粘包。(发送方的缓存机制)。
2.接收数据只接收一部分,下次接收会继续上次接收数据。(接收方的缓存机制)
只发生在TCP协议。
问题的根源:
接收方不知道消息的大小
解决方案:
1.发送方提供数据大小
2.利用struct模块调用.pack将长度打包header报头发送
3.接收方利用struct调用.unpack解包header报头取出长度
案例:利用subprocess模拟终端命令输入
''' 客户端 1、连接服务 2、发送命令 3、接收header报头 4、struct.unpack header报头得到字典长度 5、利用字典长度接收字典 6、拿出字典里面真实数据长度 7、分段接收真实数据 '''
''' 服务端: 1、开启服务 2、接收客户端命令 3、利用subprocess返回命令结果res 4、构造res数据的字典 5、序列化字典,得出序列化后的字典长度 6、利用struct模块构造字典长度的header头 7、发送header头 8、发送字典 9、发送真实数据 '''
client.py:
import socket import struct import json IP = '127.0.0.1' PORT = 8001 client = socket.socket() client.connect((IP, PORT)) while True: cmd = input('>>>').strip() client.send(cmd.encode('utf-8')) # 接收字典报头 data = client.recv(4) dict_size = struct.unpack('i', data)[0] # 接收字典数据 dict_data = client.recv(dict_size) dic = json.loads(dict_data.decode('utf-8')) # 取出数据长度 file_size = dic.get('file_size') #接收真实数据 recv_size = 0 real_data = b'' while recv_size < file_size: data = client.recv(1024) real_data += data recv_size += len(data) print(real_data.decode('utf-8'))
server.py
import socket import subprocess import struct import json IP = '127.0.0.1' PORT = 8001 server = socket.socket() server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) server.bind((IP, PORT)) server.listen(5) while True: conn, addr = server.accept() while True: try: print('客户端地址:', addr) cmd = conn.recv(1024) obj = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) res = obj.stdout.read() + obj.stderr.read() # 构造一个字典 dic = {'name': 'jason', 'file_size': len(res), 'info': 'great'} dump_dict = json.dumps(dic) # 制作字典报头 header = struct.pack('i', len(dump_dict)) # 发送字典报头 conn.send(header) # 发送字典 conn.send(dump_dict.encode('utf-8')) # 发送真实数据 conn.send(res) except ConnectionResetError as e: break conn.close()
标签:第二十八,struct,header,socket,字典,data,size 来源: https://www.cnblogs.com/AbrahamChen/p/11323021.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。