Python UDP協議黏包解決

第一種方案

服務端:

import socket
import subprocess

server = socket.socket()
ip_prot = ('127.0.0.1',8000)

server.bind(ip_prot)

server.listen()

conn,addr = server.accept()
while True:
    from_client_cmd = conn.recv(2014)
    print(from_client_cmd.decode('utf8'))

    # 接收到客戶端發送來的指令,並在服務端執行
    sub_obj = subprocess.Popen(
        from_client_cmd.decode('utf8'),
        shell = True,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE
    )
    # 統計長度
    std_msg = sub_obj.stdout.read()
    std_msg_len = len(std_msg)
    # 首先將數據長度的數據類型轉換成bytes類型
    std_bytes_len = str(len(std_msg)).encode('utf-8')
    print("執行結果長度",len(std_msg))
    # 將長度發送給客戶端
    conn.send(std_bytes_len)
	#接收客戶端返回消息,是否收到
    status = conn.recv(1024)
    if status.decode('utf-8') == 'ok':
        conn.send(std_msg)
    else:
        print("no")

客戶端:

import socket

client = socket.socket()
client.connect(('127.0.0.1',8000))

while 1:
    cmd = input("[commend]>")
    client.send(cmd.encode('utf8'))
	# 接收服務端發送的長度信息
    server_res_len = client.recv(1024).decode('utf-8')
    #回覆信息確認收到
    client.send(b'ok')
    print("服務端消息長度:",server_res_len)
	# 接收消息長度爲服務端發送的長度
    server_cmd_re = client.recv(int(server_res_len))
    print(server_cmd_re.decode('gbk'))

服務端將執行後的結果統計出長度,發送給客戶端,客戶端接收後將長度改爲此值

雖然解決了但還是多了一次收發消息過程

struct 模塊

import struct
# 數字轉換字節
a = 100
byt = struct.pack('i',a)
print(byt)
# 字節轉化數字
int_a = struct.unpack('i',byt)
print(int_a[0])

服務端:

import socket
import subprocess
import struct

server = socket.socket()
ip_prot = ('127.0.0.1',8000)

server.bind(ip_prot)

server.listen()

conn,addr = server.accept()
while True:
    from_client_cmd = conn.recv(1024)
    print(from_client_cmd.decode('utf8'))

    # 接收到客戶端發送來的指令,並在服務端執行
    sub_obj = subprocess.Popen(
        from_client_cmd.decode('utf8'),
        shell = True,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE
    )
    # 統計長度
    std_msg = sub_obj.stdout.read()
    std_msg_len = len(std_msg)

    print("執行結果長度",len(std_msg))
    # 添加struct
    msg_int_struct = struct.pack('i',std_msg_len)
    # bytes 類型數據可以互相加
    conn.send(msg_int_struct + std_msg)

客戶端

import socket
import struct

client = socket.socket()
client.connect(('127.0.0.1',8000))

while 1:
    cmd = input("[commend]>")
    client.send(cmd.encode('utf8'))

    server_res_len = client.recv(4)
    # 只接收前四個字節,也就是服務端添加的,將字節類型轉換賦值
    msg_len = struct.unpack('i',server_res_len)[0]

    print("服務端消息長度:",msg_len)

    server_cmd_re = client.recv(int(msg_len))
    print(server_cmd_re.decode('gbk'))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章