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个字节长度
  • 相关阅读:
    git三种模式及常用命令
    git remote
    页面中添加qq客服
    用ubuntu里的vim搭建一个apache2+php+mysql环境一路踩的坑
    jQuery无new创建对象原理
    国崛战略
    计算机公开课推荐 2019.8
    Unable to preventDefault inside passive event listener due to target being treated as passive 怎么办?
    VUE事件修饰符.passive、.capture、.once实现原理——重新认识addEventListener方法
    看各类框架源码淘来的一些JavaScript技巧
  • 原文地址:https://www.cnblogs.com/wualin/p/9787287.html
Copyright © 2011-2022 走看看