Python网络编程,粘包分包问题的解决

Posted wshenJin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python网络编程,粘包分包问题的解决相关的知识,希望对你有一定的参考价值。

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网络编程,粘包分包问题的解决的主要内容,如果未能解决你的问题,请参考以下文章

Netty入门解决TCP粘包/分包的实例

libevent粘包分包解决方案:bufferevent + evbuffer

解决粘包问题

网络 -- TCP概述三次握手四次挥手粘包分包数据分段

网络 -- TCP概述三次握手四次挥手粘包分包数据分段

Socket分包,封包,粘包