1. 程式人生 > >Python網絡編程,粘包、分包問題的解決

Python網絡編程,粘包、分包問題的解決

tde 網絡 ons scope time mib struct imp multicast

tcp編程中的粘包、分包問題的解決:
參考:https://blog.csdn.net/yannanxiu/article/details/52096465

服務端:

#!/bin/env python
# -*- coding:utf-8 -*-

import socket
import time
import struct
import json
import socket
import sys

class SockPackBody():
    def __init__(self , data_buffer = bytes() , header_size = 4):
        self.data_buffer = data_buffer
        self.header_size = header_size
        self.header = None
        self.body_size = 0
        self.body = None
    def PackBody(self , sock):
        while True:
            ‘‘‘一次接收循環‘‘‘
            recv_pkg = sock.recv(1024)
            if not recv_pkg and len(self.data_buffer) == 0 :
                ‘‘‘connect closed , and no data in buffer.‘‘‘
                return None
            self.data_buffer += recv_pkg
            if len(self.data_buffer) < self.header_size:
                ‘‘‘接收到的數據包小於self.headerSize,說明連包頭都沒接受完整‘‘‘
                continue
            self.header = struct.unpack("!1I" , self.data_buffer[:self.header_size])
            self.body_size = self.header[0]
            #分包
            if len(self.data_buffer) < self.header_size + self.body_size:
                ‘‘‘接收到的數據包小於self.header_size + self.body_size,說明整個數據包都沒接受完整‘‘‘
                continue
            self.body = self.data_buffer[self.header_size:self.header_size + self.body_size]
            #粘包
            self.data_buffer = self.data_buffer[self.header_size + self.body_size:]
            return self.body

if __name__ == ‘__main__‘:
    sock_pkger = SockPackBody()
    sock = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
    sock.bind((‘0.0.0.0‘ , 6688))
    sock.listen(5)
    agent_sock , agent_addr = sock.accept()
    n = 1
    while True:
        ‘‘‘一次連接(會話)循環‘‘‘
        recv_data = sock_pkger.PackBody(agent_sock)
        if not recv_data:
            agent_sock.close()
            break
        print recv_data

客戶端:

import socket
import time
import struct
import json
import sys

reload(sys)
sys.setdefaultencoding(‘utf-8‘)

serve_host = "localhost"
server_port = 6688

class PkgBuildHeader(object):
    def __init__(self, body_size ,):
        self.pack_header = struct.pack("!1I", body_size)

if __name__ == ‘__main__‘:
    client = socket.socket()
    client.connect(serve_host , server_port)

    # 正常數據包定義
    body = ‘‘‘Link encap:Ethernet  HWaddr 00:0C:29:EF:84:A3  
          inet addr:192.168.31.140  Bcast:192.168.31.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:feef:84a3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:236844 errors:0 dropped:0 overruns:0 frame:0
          TX packets:233949 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:107658740 (102.6 MiB)  TX bytes:41874253 (39.9 MiB)
        ‘‘‘
    header = PkgBuildHeader(len(body))
    sendData1 = header.pack_header + body.encode()
    
    # 分包數據定義
    header = PkgBuildHeader(len(body))
    sendData2_1 = header.pack_header+body[:20].encode()
    sendData2_2 = body[20:].encode()

    # 粘包數據定義
    body1 = "Link encap:Ethernet  HWaddr 00:0C:29:EF:84:A3"
    header1 = PkgBuildHeader(len(body1))
    body2 = "RX bytes:107658740 (102.6 MiB)  TX bytes:41874253 (39.9 MiB)"
    header2 = PkgBuildHeader(len(body2))
    sendData3 = header1.pack_header+body1.encode()+header2.pack_header+body2.encode()

    # 正常數據包
    client.send(sendData1)
    time.sleep(30)

    # 分包測試
    client.send(sendData2_1)
    time.sleep(1)
    client.send(sendData2_2)
    time.sleep(3)

    # 粘包測試
    client.send(sendData3)
    time.sleep(3)
    client.close()

Python網絡編程,粘包、分包問題的解決