在socket网络编程中,都是端到端通信,由客户端端口+服务端端口+客户端IP+服务端IP+传输协议组成的五元组可以明确的标识一条连接。在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机制来分辨这些数据。

1.Q:什么是TCP粘包问题?
TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。

2.Q:造成TCP粘包的原因
(1)发送方原因

TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:

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

Nagle算法造成了发送方可能会出现粘包问题

(2)接收方原因

TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。

3.Q:什么时候需要处理粘包现象?
如果发送方发送的多组数据本来就是同一块数据的不同部分,比如说一个文件被分成多个部分发送,这时当然不需要处理粘包现象
如果多个分组毫不相干,甚至是并列关系,那么这个时候就一定要处理粘包现象了

4.Q:如何处理粘包现象?
(1)发送方

对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。

(2)接收方

接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。

(2)应用层

应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。

解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每条数据的长度呢?

1、格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。

2、发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。

5.Q:UDP会不会产生粘包问题呢?
TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。

UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。

举个例子:有三个数据包,大小分别为2k、4k、6k,如果采用UDP发送的话,不管接受方的接收缓存有多大,我们必须要进行至少三次以上的发送才能把数据包发送完,但是使用TCP协议发送的话,我们只需要接受方的接收缓存有12k的大小,就可以一次把这3个数据包全部发送完毕。

什么是TCP粘包?怎么解决TCP粘包问题?相关推荐

  1. idea 导出jar包 及 解决缺少jar包依赖问题

    1.这里啰嗦下怎么创建一个module 参考 idea中复制module和module中的蓝色tag出现的方法 2.idea 导出jar包 参考 idea打包java可执行jar包 文章有一处图片有冲 ...

  2. 网络TCp数据的传输设计(黏包处理)

    //1.该片为引用别人的文章:http://www.cnblogs.com/alon/archive/2009/04/16/1437599.html 解决TCP网络传输"粘包"问题 ...

  3. 解决TCP网络传输“粘包”问题

    当前在网络传输应用中,广泛采用的是TCP/IP通信协议及其标准的socket应用开发编程接口(API).TCP/IP传输层有两个并列的协议:TCP和UDP.其中TCP(transport contro ...

  4. 《精通并发与Netty》学习笔记(13 - 解决TCP粘包拆包(一)概念及实例演示)

    一.粘包/拆包概念 TCP是一个"流"协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的 ...

  5. UNIX网络编程——解决TCP网络传输“粘包”问题

           当前在网络传输应用中,广泛采用的是TCP/IP通信协议及其标准的socket应用开发编程接口(API).TCP/IP传输层有两个并列的协议:TCP和UDP.其中TCP(transport ...

  6. golang 解决 TCP 粘包问题

    什么是 TCP 粘包问题以及为什么会产生 TCP 粘包,本文不加讨论.本文使用 golang 的 bufio.Scanner 来实现自定义协议解包. 协议数据包定义 本文模拟一个日志服务器,该服务器接 ...

  7. c#解决TCP“粘包”问题

    c#解决TCP"粘包"问题 参考文章: (1)c#解决TCP"粘包"问题 (2)https://www.cnblogs.com/wangjun8868/p/71 ...

  8. golang解决TCP粘包问题

    6行代码解决golang TCP粘包 转自:https://studygolang.com/articles/12483 什么是TCP粘包问题以及为什么会产生TCP粘包,本文不加讨论.本文使用gola ...

  9. Netty解决TCP的粘包和分包(二)

    2019独角兽企业重金招聘Python工程师标准>>> Netty解决TCP的粘包和分包(二) 使用LengthFieldBasedFrameDecoder解码器分包 先看一下这个类 ...

  10. Linux socket编程(一):客户端服务端通信、解决TCP粘包

    一.服务端程序 服务端程序工作流程: 创建socket →\rightarrow→ 绑定监听的IP地址和端口 →\rightarrow→ 监听客户端连接 →\rightarrow→ 接受/发送数据.对 ...

最新文章

  1. linux系统编程:线程原语
  2. 02 判断某个字符串是否由一个子字符串重复组成
  3. ***PHP 遍历数组的方法foreach
  4. corosync+pacemaker在centos7上的安装,配置简述
  5. javaWeb服务详解(含源代码,测试通过,注释) ——applicationContext.xml
  6. leetcode1302. 层数最深叶子节点的和(深度优先搜索)
  7. python中怎么计算_python中的加减乘除运算
  8. How to create a hyperlink in SQL Server Reporting Services
  9. ip扫描工具之traceroute/nmap/fping
  10. html设置编剧,编剧必备之电影剧本创作六大基本步骤
  11. Windows10系统安装详细教程
  12. DataSource 详解
  13. codingdojo kata 之fizzbuzz
  14. Guava中基础工具类Joiner的使用字符串拼接方法 joiner.on
  15. Windows批处理 - 小程序大作用
  16. TopLevel和Topmost
  17. LED的高显指是什么意思?
  18. MS-TCT:InriaSBU提出用于动作检测的多尺度时间Transformer,效果SOTA!已开源!(CVPR2022)...
  19. Temporal Shift Module(TSM) 部署在自己电脑上并训练自己的数据集
  20. kfb转tif后信息丢失的解决方案

热门文章

  1. fortran程序设计2011年注册电气工程师基础考试大纲3
  2. 云计算中的第二个boss——网络虚拟化
  3. 爱普生EPSON打印机 ME1+ (ME1)清零软件及方法
  4. 咪咕音乐播放器 ubuntu 安装详解
  5. JS 替换字符串中指定字符
  6. 虚拟打印机安装后没了该怎么办
  7. 三菱PLC项目案例学习之PLC控制伺服或步进电机带动丝运行案例
  8. python凹多边形分割_Unity 凹多边形三角剖分
  9. js根据身份证获取性别、年龄、出生日期及根据出生日期获取年龄
  10. [NOI题库]1.3编程基础之算术表达式与顺序执行 题解(一)