码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2018-03-26 12:32:34      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:ram   cli   one   errors   粘包   connect   set   data   gpo   

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网络编程,粘包、分包问题的解决

标签:ram   cli   one   errors   粘包   connect   set   data   gpo   

原文地址:https://www.cnblogs.com/wshenjin/p/8649645.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!