zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    路径
    aspx.cs调用js方法
    计算字符串中每种字母出现的次数
    [转载]获取2个集合List<T>的共同元素
    [转载]行列转换
    [转载]UNION合并查询
    [转载]Case When Then
    [转载]CAST-CONVERT两个函数进行类型转换时的异同点
    [转载]404错误页面设置
    [转载]JQ小知识
  • 原文地址:https://www.cnblogs.com/wshenjin/p/8649645.html
Copyright © 2011-2022 走看看