python中黏包问题的解决
1.在前面我们知道tcp容易产生黏包的问题,而udp不会产生黏包的问题,但是会产生丢包的问题,tcp应用的场景很多所以黏包问题必须要解决。
1.解决黏包问题第一种方法,我们知道黏包问题是由于tcp的优化算法将两个不太大的数据包合并了一起发送的,这种情况一般出现在连续使用几个send()出现的,所以我们如果知道要发送的数据有多大我们就可以设置接收的大小,这样就可以刚好能把所有的数据接收完。下面是具体的步骤细节见代码
这是远程执行cmd命令并返回结果的程序
server端代码
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:
cmd = input('>>>')
conn.send(bytes(cmd,encoding='utf-8'))
num = conn.recv(1024).decode('utf-8')
conn.send(bytes('ok',encoding='utf-8'))
ret = conn.recv(num)
print(ret.decode('gbk'))
conn.close()
sk.close()
client端代码
import socket
import struct
import subprocess
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
cmd = sk.recv(1024).decode('utf-8')
ret = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
std_out = ret.stdout.read()
std_err = ret.stderr.read()
sk.send(bytes(str(len(std_err)+len(std_out)),encoding='utf-8'))
sk.recv(1024)
sk.send(std_out)
sk.send(std_err)
sk.close()
总结这种解决数据的黏包现象有一个问题是多了一次连接延时要接收一个没有用的数据 ok,如何不需要接收ok就能解决黏包现象呢?这就需要下面这种解决方案
2.用struct模块解决黏包现象
server端代码
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:
cmd = input('>>>')
conn.send(bytes(cmd,encoding='utf-8'))
num = conn.recv(1024)
num = struct.unpack('i',num)[0]
ret = conn.recv(num)
print(ret.decode('gbk'))
conn.close()
sk.close()
client端代码
import socket
import struct
import subprocess
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
cmd = sk.recv(1024).decode('utf-8')
ret = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
std_out = ret.stdout.read()
std_err = ret.stderr.read()
num = len(std_err) + len(std_out)
num = struct.pack('i',num)
sk.send(num)
sk.send(std_out)
sk.send(std_err)
sk.close()
|