Python socket粘包問題
阿新 • • 發佈:2018-07-08
decode ack listen RoCE shell process ces 粘包問題 多少
server端配置:
import socket,subprocess,struct from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind((‘127.0.0.1‘,8080)) server.listen(5) while True: conn,client_addr=server.accept() while True: try: cmd=conn.recv(1024) if len(cmd) == 0:break obj=subprocess.Popen( cmd.decode(‘utf-8‘), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) out=obj.stdout.read() #bytes類型 err=obj.stderr.read() print(len(out+err))# 解決粘包問題的步驟,先發型數據的長度 total_size=len(out)+len(err) #數據類型,1.變為bytes類型 2.還是個固定長度 #1.制作固定長度的包頭 header=struct.pack(‘i‘,total_size) #2.發送報頭 conn.send(header) #固定數據報的head頭的大小(自定義數據) #下面是發送真是的數據 # conn.send(out+err)#2個包是一起發過去的,因為間隔短 conn.send(out) conn.send(err) #發過去的整體是一個數據報=報頭+數據部分 except ConnectionResetError: break conn.close() server.close()
client端配置:
import socket import socket,struct client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect((‘127.0.0.1‘,8080)) while True: cmd=input(‘輸入執行的命令:‘) if len(cmd) == 0: continue client.send(cmd.encode(‘utf-8‘)) #1.先收固定長度的的包頭默認stuck就是固定了長度為4 header=client.recv(4) #第二次再收不是下一個包頭,是上次命令的殘留 #2.解析包頭 total_size=struct.unpack(‘i‘,header)[0] #拿到的是個元祖,元祖的0就是這個長度值 print(total_size) #3.根據包頭內的信息,收取真實數據 # client.recv(total_size) 因為現實數據量太大的時候就不行,所以考慮while循環 #思考如果數據大,total_size數據會特別大就會直接報錯 #為了解決輸入較大程序,定義一個小的變量,循環一點點就去收 recv_size=0 res=b‘‘ while recv_size < total_size: recv_data=client.recv(1024) #recv_data是bytes類型,是唯一真實的值,有多少就會收多少 res+=recv_data recv_size+=len(recv_data) print(res.decode(‘gbk‘)) client.close()
Python socket粘包問題