zoukankan      html  css  js  c++  java
  • socket模块粘包现象理解以及解决思路

    粘包现象:

    • 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小、数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制

    • 对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。所以UDP不会出现粘包问题。

    粘包现象理解:

    socket模块sned以及recv实现底层原理
    • send
      • 作用:将内存中的数据通过网卡发送出去
      • 底层原理:将数据从程序内存中拷贝到操作系统,通过操作系统调用网卡接口发送到远程
    • recv
      • 作用:接收远程发送的数据,传入参数单位为字节
      • 底层原理:网卡接收远程发过来的数据,然后将数据从操作系统内存拷贝到应用程序内存中

    不管是recv还是send都不是直接发送或者接收对方的数据,而是操作自己的操作系统的内存,并且不是一个send对应一个recv,是根据recv接收数据的大小而决定

    TCP协议传输优化算法:Nagle算法
    • 将数据比较小的包,并且时间间隔很短的包合并成一个包,调一次网卡io将数据发送到远程,节省调用网卡io的时间,粘包现象是TCP底层传输优化算法造成的。

    粘包现象结局思路

    1. 客户端循环接收数据,使用while循环判断数据是否接收完毕
    2. 服务端返回诗句是打包报头发送给客户端,客户端根据报头发送的数据长度截取发送数据的真实长度
    服务端:
    1. 制作固定长度的报头
    2. 将报头打包发送给客户端(使用struct模块打包数据)
    3. 再发送真实数据,通过while循环判断是否接收完毕,接收完了则跳出循环
    客户端
    1. 接收报头,指定接收报头的长度,使用struct打包将服务端发送的报头按照指定模式解析
    2. 解析报头获得真实数据的长度描述

    可使用内置模块struct打包与解析数据长度,

    1. i模式:4个字节长度
    2. l模式:8个字节长度
  • 相关阅读:
    Java-idea-FindBugs、PMD和CheckStyle对比
    Java-idea-PMD源文件级别潜在bug查看
    Java-idea-FindBugs字节码级别潜在bug查看
    Java-idea-Checkstyle自动化代码规范检查
    js-jquery-从SweetAlert到SweetAlert2
    js-jquery-SweetAlert2【二】配置与方法
    js-jquery-SweetAlert2【三】INPUT TYPES
    js-jquery-对象与JSON字符串互相转换
    js-jquery-数组遍历
    java-小技巧-001-Long序列化到前端js不支持
  • 原文地址:https://www.cnblogs.com/wualin/p/9787287.html
Copyright © 2011-2022 走看看