TCP-IP协议与粘包

TCP是面向字节流的协议,无消息边界,导致应用层出现粘包和拆包问题。成因包括TCP缓冲区机制、Nagle算法攒包、接收方读取不完整及IP分片。常见解决方法有固定长度、分隔符法、消息头+消息体(最常用),以及关闭Nagle算法(仅辅助)。UDP因面向报文,天然无粘包。粘包本质是应用层需自行处理消息边界。

一、TCP/IP协议

数据封装过程:

TCP首部、IP首部:

二、TCP 粘包

TCP 是面向字节流协议,没有消息边界!UDP 面向报文,不存在粘包

粘包产生原因:

TCP 无消息边界 + 缓冲区缓存 + Nagle 攒包 + IP 分片

1.TCP 本身特性:面向字节流 + 收发缓冲区

TCP 不保留应用层消息边界,数据只是一串连续字节;内核有发送缓冲区、接收缓冲区,数据先放缓冲区,不是调用一次 send 就立刻发一个独立包。

2.发送方:Nagle 算法(重点)

Nagle 会把多次小数据攒起来,合并成一个大报文段一起发送,减少小包数量,提升网络效率 → 多条消息粘在一起(粘包)。

3.接收方缓冲区读取

接收端内核收到数据放接收缓冲区;应用程序 recv 一次读的字节数不确定,一次读可能把多条消息一起读出来。

4.网络链路:IP 分片

数据包太大超过 MTU,网络层会分片传输,一条消息被拆成多片,也就是拆包。

粘包解决方法:

1.固定长度

  • 每次消息大小固定;接收方每次固定读对应长度。
  • 缺点:浪费流量,短消息也要补齐到固定大小。

2.特殊分隔符(分隔符法)

  • 消息末尾加特殊标记(比如\n、\r\n),接收方读到分隔符代表一条消息结束。
  • 缺点:消息内容里面不能出现这个分隔符,否则解析错乱。

3.消息头 + 消息体

  • 头部固定字节,存放消息体长度(比如前 4 字节表示后面数据有多长),后面跟着真实消息内容;
  • 流程:先读头部拿到长度 → 再根据长度读取对应字节的消息体。
  • 优点:灵活、稳定,项目最常用。

4.关闭 Nagle 算法(不推荐单独用来解决粘包)

  • setsockopt设置 TCP_NODELAY,关闭 Nagle,有数据立刻发。
  • 注意:关闭 Nagle 不能根治粘包!只是减少攒包,缓冲区依然会带来粘包,一般配合上面方案一起使用

1.粘包是 TCP字节流特性自带的正常现象,TCP 只管可靠传输字节,不区分应用消息,必须应用层自己做消息边界

2.UDP 不会粘包:UDP 面向报文,一次 sendto 对应一个报文,内核保留报文边界

3.粘包、拆包本质是同一个问题:应用层分不清消息起点终点

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值