zoukankan      html  css  js  c++  java
  • 粘包问题

    粘包问题

    返回首页

    粘包问题:是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段,若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发出,这样接收方就收到了粘包数据。使用的算法是Nagle。

    TCP协议是流式传输,没有开始没有结束,所以也就不知道在哪里分开粘结点。

    自制报头解决粘包问题:

    报头:固定长度、包含对将要发送的数据添加描述信息。

     client端:

    import socket
    import struct
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ip_port = ('127.0.0.1', 8081)
    phone.connect(ip_port)
    
    # 通信循环
    while True:
        # 发消息
        cmd = input('>>: ').strip()
        if not cmd: continue
        phone.send(bytes(cmd, encoding='utf-8'))
    
        # 收报头 收4个字节
        baotou=phone.recv(4)
        # 定义的i的报头长度,用unpack去解报头,第0个是数据长度
        data_size=struct.unpack('i',baotou)[0]
    
        # 收数据,
        recv_size=0
        recv_data=b''
        while recv_size < data_size:
            data=phone.recv(1024)
            recv_size+=len(data)
            recv_data+=data
    
        print(recv_data.decode('utf-8'))
    
    phone.close()

    Server端:

    #coding:utf-8
    import socket
    import struct
    import subprocess
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    ip_port=('127.0.0.1',8081)
    phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    phone.bind(ip_port)
    phone.listen(5)
    
    #链接循环
    while True:
        conn,addr=phone.accept()
        print('client addr',addr)
        #通讯循环
        while True:
            try:
                cmd=conn.recv(1024)
                res=subprocess.Popen(cmd.decode('utf-8'),
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
                out_res=res.stdout.read()
                err_res=res.stderr.read()
                # 发送报头部分
                data_size=len(out_res)+len(err_res)
                # 发送数据部分,定义报头长度为4个字节
                conn.send(struct.pack('i',data_size)) #struck.pack是打包,i是代表4个字节
                conn.send(out_res)
                conn.send(err_res)
    
            except Exception:
                break
    
        conn.close()
    phone.close()

    ------- END ------

  • 相关阅读:
    JS中document对象和window对象有什么区别
    jQuery parent.append和$after的区别
    使用CFURLCreateStringByAddingPercentEscapes进行URL编码
    JQuery中==与===、$("#")与$("")的区别
    理解JavaScript中的arguments,callee,caller,apply
    使用自己的ClassLoader实现热替换
    TextBox 英文文档
    easyui的textbox和validatebox的 赋值区别
    jquery的$.extend、$.fn.extend、 jQuery.extend( target, object1, [objectN])作用及区别
    jQuery 遍历
  • 原文地址:https://www.cnblogs.com/george92/p/14890212.html
Copyright © 2011-2022 走看看