一、粘包

1、定义

指发送方发送的若干数据包在接收方接收时粘成一团,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

2、产生的原因

(1)发送方的原因

TCP默认使用 Nagle 算法,而 Nagle 算法主要做如下两件事情:

  • 只有上一个分组得到确认,才发送下一个分组。
  • 收集多个小分组,在一个确认到来时一起发送。

Nagle 算法造成了发送方可能存在粘包现象。

(2)接收端的原因

接收端接收到分组时,应用层并不会立即处理,接收端将接收到的分组放到接收缓存中,然后应用程序主动从接收缓存中读取分组,当接收端接收分组的速度大于应用程序读取分组的速度时,多个包就会被存至缓存。应用程序读取时,就会读到多个首尾相连在一起的包。

3、什么时候需要处理 TCP 粘包问题。

  • 如果发送方的多个分组本来就是同一个数据的不同部分,比如一个很大的文件分成多个分组发送,这时不需要处理TCP粘包问题。
  • 如果多个分组毫不相干,甚至是并联关系,则一定要处理TCP粘包问题。

二、拆包

1、定义

发送方将一个数据包拆分成了多个数据包进行传送。

2、产生的原因

  • 要发送的数据大于 TCP 剩余缓冲区的大小。
  • 要发送的数据大于 MSS 最大报文长度。

三、如何处理TCP粘包和TCP拆包问题

无论是TCP拆包还是TCP粘包本质问题都在于无法区分包的界限,可以采用以下三种方式来区分包的界限

  1. 消息数据固定长度,但是浪费存储和网络资源。
  2. 使用分割符来区分包的界限。
  3. 数据包的头部中增加数据包长度字段。

四、代码示栗

#pragma pack(1)struct XMNPkgHeader
{// 报文的总长度(包头 + 包体)。unsigned short pkglen;// 消息类型的代码,用于区别不同的命令(消息)。unsigned short msgcode;// CRC32 校验,用于防止接收到的数据和 client 发送的数据不符的问题。int crc32;
};#pragma pack()

之所以使用 pack(1) ,目的是让包头大小更紧凑,节约流量。 由于包头的大小(headerlen)是固定的,通过 pkglen 就可以知道包体的大小(bodylen = pkglen - headerlen)。

在已知包头和包体的长度的情况下,接受数据包的时候,首先可以接收 headerlen 大小的数据,如果接收的数据不够,则下次接收包头剩余的数据,直至包头数据接收完毕。

包头数据接收完毕之后,再接收 bodylen 大小的数据,如果接收的数据不足,则接收剩下的包体的数据,直至包体的数据接收完毕。

五、总结

TCP 之所以存在拆包和粘包问题,本质就是 TCP 是面向字节流的,而 UDP 是面向报文的!

六、源码链接

https://github.com/xuchanglong/XMoon

(SAW:Game Over!)

TCPIP / 粘包和拆包的定义以及解决办法相关推荐

  1. TCP粘包和拆包的定义,产生的原因以及解决方案

    TCP粘包和拆包的定义,产生的原因以及解决方案 参考文章: (1)TCP粘包和拆包的定义,产生的原因以及解决方案 (2)https://www.cnblogs.com/yinbiao/p/110150 ...

  2. 什么是粘包和拆包,Netty如何解决粘包拆包?

    Netty粘包拆包 TCP 粘包拆包是指发送方发送的若干包数据到接收方接收时粘成一包或某个数据包被拆开接收. 如下图所示,client 发送了两个数据包 D1 和 D2,但是 server 端可能会收 ...

  3. 【Netty】入门Netty官方例子解析(三)处理一个基于流的传输 TCP粘包和拆包问题分析和解决

    关于 Socket Buffer的一个小警告 基于流的传输比如 TCP/IP, 接收到数据是存在 socket 接收的 buffer 中.不幸的是,基于流的传输并不是一个数据包队列,而是一个字节队列. ...

  4. 【Netty】Netty解决粘包和拆包问题的四种方案

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接.由于微服务往对方发送信息的时候,所有的请求都是使 ...

  5. Netty 解决粘包和拆包问题的四种方案

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://my.oschina.net/ ...

  6. Netty解决粘包和拆包问题的四种方案

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接.由于微服务往对方发送信息的时候,所有的请求都是使 ...

  7. netty 高低位转码_Netty解决粘包和拆包问题的四种方案

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接.由于微服务往对方发送信息的时候,所有的请求都是使 ...

  8. Netty是如何解决粘包和拆包问题的

    本文来说下Netty是如何解决粘包和拆包问题的 文章目录 概述 粘包和拆包 常见解决方案 Netty提供的粘包拆包解决方案 FixedLengthFrameDecoder LineBasedFrame ...

  9. 面试官问:你来讲下Netty通信中的粘包、拆包?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Java技术剑 来源:https://urlify.cn/I ...

最新文章

  1. C++计算程序耗时函数用法汇总
  2. ImportError: No module named _ssl解决方法
  3. 定义EditPlus 语法文件详解
  4. 用户管理:搭建系统微服务
  5. 从事UNIX/LInux服务器编程最方便的代码编译工具------(eclipse for c/c++)、(FileZilla)、(Secure CRT) 这三种一定要一起使用 之3...
  6. java mapreduce 实例_MapReduce -- JAVA 实例(一)计算总数
  7. linux怎么用jconsole_jconsole监控上Linux上的JVM
  8. 华为鸿蒙不再孤,华为鸿蒙OS系统不再孤单!又一款国产系统启动内测:再掀国产替代化...
  9. 数据结构与算法-黑盒与白盒测试法
  10. Django 源码阅读
  11. 记一次使用eclemma的蛋疼的测试经历
  12. Mininet与真实网络链接的方法
  13. java多线程基本概述(二)——Thread的一些方法
  14. 从外部访问Kubernetes集群中的应用
  15. 金融系统中BER-TLV的解析,更改、增加、删除TAG的实现
  16. 新建3台linux7.5部署k8s,之后的软件安装全部都在k8s
  17. SATA硬盘在安装OS时注意AHCI模式
  18. ps新手零基础知识入门教程学习_图文
  19. linux常用cat,Linux常用操作命令之cat
  20. R语言 kNN 对鸢尾花进行分类

热门文章

  1. 图形化代码阅读工具——Scitools Understand
  2. 【51CTO/BBS】请教: SQL里有没有字符串组合Join的函数??
  3. 艾伟_转载:[一步一步MVC]第五回:让TagBuilder丰富你的HtmlHelper
  4. flex+php截图Demo
  5. Nginx 301跳转踩坑总结
  6. idea设置java scala等代码自动换行
  7. Ansible Playbook企业案例:利用 playbook 安装 nginx、安装和卸载 httpd、安装mysql
  8. Hadoop集群扩容和缩容:添加白名单和黑名单
  9. Linux parted分区工具使用示例
  10. JavaFX Button和Scene点击事件代码示例