学习笔记(13):Python网络编程并发编程-解决粘包问题-终极版本

Serwa ·
更新时间:2024-09-21
· 946 次阅读

立即学习:https://edu.csdn.net/course/play/24458/296244?utm_source=blogtoedu

粘包现象解决(终极版)

1.简单版的问题所在

1)报头信息不一定只是包含着命令执行结果的字节数长度,在文件传输的时候也可能包含文件名等,这时候就需要用到字典来将文件的相关信息进行封装

2)struct模块中struct.pack('l',数据长度),这个数据长度是有限制的,当发送的文件的字节数长度超过时,就会出现错误!

2.知识点

1)字典转为bytes类型:首先使用json.dumps(dict)将字典序列化为json字符串,然后使用.encode('utf-8')对json字符串进行编码成bytes类型

2)bytes类型解析为字典:首先对bytes进行解码成json字符串,然后将json字符串反序列为字典即可(json.loads(json字符串))

3.关键代码

''' 服务端 ''' ...... #2处理命令,执行命令并且获得命令得到的结果 obj = subprocess.Popen(cmd.decode('utf-8'),shell=True, stdout=subprocess.PIPE,#将正确运行命令得到的结果传给管道stdout中 stderr=subprocess.PIPE)#将没有正确运行命令得到的返回信息存放在stderr管道中 stdout = obj.stdout.read() stderr = obj.stderr.read() total_size = len(stderr + stdout) #1)制作包含文件名和文件大小的文件头,用字典实现 headers_dict = { "filename":"nianbao", "filedata":"2020/03/09", "total_size":total_size } #2)将字典先序列化成惊悚字符串,再转为bytes类型文件头 headers_json = json.dumps(headers_dict) #3)获取bytes类型的长度 headers_bytes = headers_json.encode('utf-8') headers_size = len(headers_bytes) #4)将bytes类型文件头长度定制为固定长度的报头 header = struct.pack('i',headers_size) #5)向客户端发送报头 conn.send(header) #6)向客户端发送包含文件信息的字典 conn.send(headers_bytes) #7)向客户端发送真实命令执行的结果 data = stdout + stderr conn.send(data) ...... ''' 客户端 ''' ...... #4、接收服务器返回来的数据recv() #1)先接收由服务器返回来的报头,报头是固定长度的,因此取前面4字节的数据即为报头 header = phone.recv(4)#返回的是一个对象 #2)解析报头,得到bytes类型的文件头长度 obj_truple = struct.unpack('i',header)#返回的是一个元组 headers_bytes_size = obj_truple[0]#取元组第一个元素即为总字节数 #3)接收bytes类型的文件头数据 headers_bytes = phone.recv(headers_bytes_size) #4)将bytes类型的文件头数据反序列化成字典 headers_json = headers_bytes.decode('utf-8') headers_dict = json.loads(headers_json) #5)从字典中取出字命令执行结果字节总长度 total_size = headers_dict['total_size'] #6)接收返回的数据 recv_size = 0 data = b'' while recv_size < total_size: recv_data = phone.recv(1024)#接收小于1024bytes的数据 recv_size += len(recv_data) data += recv_data #7)打印字典并且打印返回的数据 print(headers_dict) print('服务器返回来的数据:',data.decode('gbk')) print('*'*50) ......

4.完整代码:在上一篇笔记的基础上修改一下即可


作者:python_AI_fans



学习笔记 并发编程 版本 并发 学习 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号