1. 程式人生 > >Python socket粘包問題

Python socket粘包問題

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粘包問題