1. 程式人生 > 實用技巧 >Python socket程式設計-進階2

Python socket程式設計-進階2

解決 粘包現象

所謂粘包現象:

  當一端發生資料的容量大於另外一端一次接收容量,導致另外一端一次只能接受部分資料,其餘剩下的資料將儲存在快取裡面,當一端再次傳送資料的時候,此時另外一端將先在快取裡面取上次剩下的部分資料後在來讀取這次傳送的資料,

這樣就導致傳送和接收的資料不一致。

解決方法:

  採用先發送資料大小,再發送資料

server端:

import  socket,subprocess
import  struct


tcp=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp.bind(('localhost',8080,))
tcp.listen(
5) while True: conn,address=tcp.accept() while True: try: command=conn.recv(1024).decode('utf-8') res=subprocess.Popen(command,shell=True,stderr=subprocess.PIPE,stdin=subprocess.PIPE,stdout=subprocess.PIPE) err=res.stderr.read() if err: cmd_msg
=err else: cmd_msg=res.stdout.read() if not cmd_msg: # 防止指令是正確的,但是結果卻是空的,無論是客戶端還是服務端都不能發生空訊息! cmd_msg='沒有資料!'.encode('gbk') """ 解決粘包思路: 1. 先發送資料的長度到客戶端 struct.pack('i',len(cmd_msg)) 這是一個庫, 將一個數據打包,第一個引數為標識(4個位元組)也就是傳送的大小,第二個引數為要打包的資料 2. 再發送資料
""" size=struct.pack('i',len(cmd_msg)) conn.send(size) conn.send(cmd_msg) except Exception as e: print(e) break conn.close() tcp.close()

client端:

import  socket
import  struct
tcp=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp.connect(('localhost',8080,))



while True:
    command=input('>>>')
    if not command:continue


    tcp.send(command.encode('utf-8'))


    """
        解決粘包思路:
            1. 先接收資料長度
                 struct.unpack('i',size)[0] 這是一個庫, 將一個打包資料解壓
            2. 再按照資料長度迴圈讀取資料
    """
    size=tcp.recv(4)
    length=struct.unpack('i',size)[0]

    recv_size=0
    recv_msg=b''
    while recv_size<length:
        recv_msg+=tcp.recv(100)
        recv_size=len(recv_msg)


    recv_msg=recv_msg.decode('gbk')
    print(recv_msg)