TCP粘包

什么是粘包?

粘包 就是 接收方一次性读取了发送方多次发送的数据包

造成粘包有以下两个原因:

1、 由于TCP是面向流的协议,数据与数据之间是没有界限。接收方可能同时读取多个数据包读取

2、 当传输的数据比TCP头部的字节还少时,大量的发送这种数据包,会加重网络的负担。所以引入了Nigle算法,将连续的多个小分组拼接到一个TCP报文中发送。这也会造成粘包。

粘包的解决方案

第一种粘包:

在要发送的数据头部固定n个字节来标识要发送的数据的长度,在读取的时候,首先读取长度,然后根据长度再来读取对应的数据。

第二种粘包:

将Nigle算法关闭,然后按照第一种粘包的解决方案来执行

TCP是指发送方发送的多个数据在传输过程中被合并成一个数据,接收方接收到的数据也是合并后的数据。C++ TCP的原因是TCP协议的Nagle算法和接收方缓冲区的大小限制。Nagle算法会将小的数据合并成一个大的数据发送,而接收方缓冲区的大小限制会导致接收方无法及时处理接收到的数据,从而造成现象。 解决C++ TCP的方法有以下几种: 1.设置TCP_NODELAY选项,禁用Nagle算法,使得每个数据都立即发送。 2.在发送的数据中添加特殊的分隔符,接收方根据分隔符将数据拆分成多个数据。 3.在发送的数据中添加数据长度信息,接收方根据长度信息将数据拆分成多个数据。 以下是C++ TCP的解决方法示例: 1.禁用Nagle算法 ```c++ int flag = 1; setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)); ``` 2.添加分隔符 ```c++ // 发送端 string msg = "hello|world|"; send(sockfd, msg.c_str(), msg.size(), 0); // 接收端 char buf[MAXSIZE]; string data; while (true) { int len = recv(sockfd, buf, MAXSIZE, 0); if (len <= 0) { break; } data += string(buf, len); while (true) { int pos = data.find("|"); if (pos == string::npos) { break; } string msg = data.substr(0, pos); data = data.substr(pos + 1); // 处理接收到的数据 } } ``` 3.添加数据长度信息 ```c++ // 发送端 string msg = "hello world"; int len = msg.size(); send(sockfd, (char *)&len, sizeof(len), 0); send(sockfd, msg.c_str(), msg.size(), 0); // 接收端 char buf[MAXSIZE]; int len; while (true) { int ret = recv(sockfd, (char *)&len, sizeof(len), 0); if (ret <= 0) { break; } int n = 0; while (n < len) { int len1 = min(MAXSIZE, len - n); int ret1 = recv(sockfd, buf, len1, 0); if (ret1 <= 0) { break; } n += ret1; // 处理接收到的数据 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值