首先说为什么会粘包,在py2上运行时,服务器把两次发送的操作强制的合成一次发送给客户端,所以 粘在一起了,因为python3的版本是可以的,但是有的时候python3也会出现粘包现象。
解决粘包的问题有两种方法:
1 可以先sleep一下,这个样子就可以使缓冲区超时,就不在等下一次的了,这样就可以和下一条命令隔离开了
2 我在服务端来一个等待客户端确认,就ok了,这个确认不需要我们用户输入,而是客户端自动的给你来这个响应,就是说,客户端自动的写好代码,自动的给服务器一个响应,只要收到服务端的数据大小,我就立刻给服务器一个响应,就是在第一次send和第二次send之前插入一个交互,就能把数据分开了。
下面也有两次send 的原因。
代码:中间空白分割的部分
#!usr/bin/env phthon3 # -*- coding:utf-8 -*- # _Author_:"zhang Yaoqing" import socket client = socket.socket() client.connect(("localhost", 9999)) while True: cmd = input(">>>:").strip() if len(cmd) == 0: continue client.send(cmd.encode("utf-8")) cmd_res_size = client.recv(500) # 接收命令的长度 print("命令结果大小:", cmd_res_size.decode()) client.send(‘准备好了,可以发送了‘.encode(‘utf-8‘)) # 客户端已经确认。 recevied_size = 0 # 接收客户端发来数据的计算器 recevied_data = b‘‘ # 客户端每次发来内容的计数器 while recevied_size < int(cmd_res_size.decode()): # 当接收的数据大小 小于 客户端发来的数据 cmd_res = client.recv(500) recevied_size += len(cmd_res) # 每次收到的服务端的数据有可能小于1024,所以必须用len判断 recevied_data += cmd_res else: print(recevied_data.decode("utf-8", "ignore")) print("cmd res receive done ....", recevied_size)
#!usr/bin/env phthon3 # -*- coding:utf-8 -*- # _Author_:"zhang Yaoqing" import socket, os server = socket.socket() server.bind(("localhost", 9999)) server.listen(5) while True: conn, addr = server.accept() print("new addr:", addr) print(‘conn‘,conn) while True: data = conn.recv(500) if not data: print("客户端已断开") break print("执行指令:", data) cmd_res = os.popen(data.decode()).read() print("before send:", len(cmd_res)) if len(cmd_res) == 0: cmd_res = "cmd has no output...." conn.send(str(len(cmd_res.encode())).encode()) # 发送服务端发送给客户端数据的长度 client_ack = conn.recv(1024) # 等待确认 conn.send(cmd_res.encode("utf-8")) # 发送服务端的数据 print("send done")
原文:https://www.cnblogs.com/littlesky1124/p/9043593.html