zoukankan      html  css  js  c++  java
  • 粘包

    粘包

    • 发生在发送端的粘包
      • 由于两个数据的发送时间间隔+数据的长度小
      • 所以由tcp协议的优化机制将两条信息作为一条信息发送出去了
      • 为了减少tcp协议中的“确认收到”的网络延迟时间
    • 发生在接收端的粘包
      • 由于tcp协议中所传输的数据无边界,所以来笔记接受的多条数据在接受端的内核的缓存端粘在了一起
    • 本质:接受信息的边界不清晰导致的

    粘包问题的解决

    • 自定义写协议1
      • 首先发送报头(与内容无关,为所遵守的协议),报头的长度为4个字节
        • 内容为即将发送的报文的字节长度
        • struct模块
          • pack能够把所有的数字都固定的转换为4个字节
      • 再发送报文
    • 自定义协议2
      • 专门用来做文件发送的协议
      • 先发送报头的字节长度
      • 再发送字典(字典中包含文件的名字、大小。。。)
      • 再发送文件的内容
    #client端
    import socket
    import struct
    
    sk = socket.socket()
    sk.connect(("127.0.0.1",9000))
    msg =b"hello"
    byte_len = struct.pack("i",len(msg)) #将任意数字转化为固定长度的四个字节,i为int类型
    sk.send(byte_len )
    sk.send(msg)
    
    msg = b"world"
    byte_len = struct.pack("i",len(msg))
    sk.send(byte_len )
    sk.send(msg)
    
    
    sk.close()
    
    #server端
    import socket
    import struct
    import time
    
    sk = socket.socket()
    sk.bind(("127.0.0.1",9000))
    sk.listen()
    
    conn,_ = sk.accept()
    time.sleep(0.1)
    byte_len = conn.recv(4)
    size = struct.unpack("i",byte_len)[0]
    msg1 = conn.recv(size) #分段量身定制
    print(msg1)
    
    byte_len = conn.recv(4)
    size = struct.unpack("i",byte_len)[0]
    msg2 = conn.recv(size)
    print(msg2)
    
    
    
    记录学习的点点滴滴
  • 相关阅读:
    MVC学习笔记(六)---遇到的小问题汇总
    C# 手写将对象转换为Json方法
    C# 使用SuperSocket
    C#生成/调用动态链接库
    Winform串口编程---接收数据demo(VSPD虚拟串口)
    js获取浏览器内核判断终端(是QQ打开还是QQ浏览器打开)
    工具函数(获取url , 时间格式化,随机数)
    node和npm的安装和镜像源的修改
    atom常用插件
    查看并关闭端口号
  • 原文地址:https://www.cnblogs.com/yangzilaing/p/14860649.html
Copyright © 2011-2022 走看看