HarmonyOS 鸿蒙Next网络编程系列6-TCP数据粘包表现及原因分析
HarmonyOS 鸿蒙Next网络编程系列6-TCP数据粘包表现及原因分析
- 什么是粘包
在基于TCP协议的端到端通讯中,如果一端连续发送两个或者两个以上的数据包,对端在一次接收时,收到的数据包数量可能大于1个,也可能是几个完整数据包加上一个完整包的一部分数据,这些统称为粘包。
2.TCP粘包示例
本文将设计一个示例演示数据粘包的表现,具体的思路是这样的:
1)使用鸿蒙应用发起TCP客户端到服务端连接。
2)服务端为回声服务器,会把收到的信息原样发回给客户端
3)TCP客户端连续发送从0到100的数字字符信息到服务端,每次发送一个数字,发送后休眠1毫秒。
4)客户端对于接受到的服务端信息在日志输出,每次一行(也就是在接受信息后面加上回车换行)
5)如果没有所谓的“粘包”问题,客户端会收到100次回复
下面详细介绍创建该应用的步骤。
步骤1:创建Empty Ability项目。
步骤2:在module.json5配置文件加上对权限的声明:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_WIFI_INFO"
}
]
这里分别添加了访问互联网和访问WIFI信息的权限。
步骤3:在Index.ets文件里添加如下的代码:
//发送测试消息到服务端
async sendTestMsg2Server() {
//执行TCP通讯的对象
let tcpSocket = socket.constructTCPSocketInstance();
await this.bind2Port(tcpSocket)
await this.connect2Server(tcpSocket)
for (let i = 0;i < 100; i++) {
await tcpSocket.send({ data: i.toString() })
await sleep(1)
}
}
步骤4:编译运行,可以使用模拟器或者真机。
步骤5:运行回声服务器(需要读者自行开发或者等我拿到鸿蒙Next权限后写一个鸿蒙版本的回声服务器),然后配置客户端的服务端地址,然后单击“测试”按钮,执行后的截图如下所示:
截图清晰表明,出现了严重的粘包情况,客户端虽然是一个个发送的,代码如下所示:
//发送测试消息到服务端
async sendTestMsg2Server() {
//执行TCP通讯的对象
let tcpSocket = socket.constructTCPSocketInstance();
await this.bind2Port(tcpSocket)
await this.connect2Server(tcpSocket)
for (let i = 0;i < 100; i++) {
await tcpSocket.send({ data: i.toString() })
await sleep(1)
}
}
但是接收的时候和发送的不一样,是一堆堆接收的,原因是什么呢?
3.TCP粘包原因分析
TCP是一种面向流的数据传输协议,传输的对象是连续的字节流,内容之间并没有明确的分界标志,严格来说,并不存在粘包的问题,而通常所说的粘包,更多的是一种逻辑上的概念,也就是人为的把TCP传输的字节流划分成了一个个的数据包,发送端确定了数据包之间的边界,但是接收端并不能保证按照数据包的边界来接收。对于本示例中发送端和接收端不匹配的情况,还可能和下面的原因有关:
1)发送端启用了Nagle算法
发送端对于小包,可能会累计起来,到了一定的数据量或者其他条件满足才发送给接收端,这是导致粘包的一个重要原因。
2)TCP的滑动窗口机制
根据滑动窗口的机制,发送端一次发送数据量的多少并不完全是由自己决定的,还要受接收端的缓存大小限制,这也会导致发送端原本计划一次发送的数据包被分为多次发送。
3)MSS和MTU分片
如果一次需要发送的数据大于MSS或者MTU时,数据会被拆分成多个包进行传输,这也会导致粘包的产生。
4)接收端不及时接收
如果接收端不能及时接收缓冲区的数据包,那么在其后的某次接收中,就会出现接收多个数据包的情况。
4.TCP粘包问题解决方案
知道了数据粘包的原因,解决起来就有方向了,大体可以分为两种方案,一种是指定数据包结束标志,另外一种是通过固定包头指定包的长度,不过这两种方案都需要服务端配合才行,因为API 9版本的鸿蒙尚未支持TCP服务端,虽然更高的10、11支持了,但是我还没有这些版本的使用权限,暂时无法编写服务端程序,等以后开放了权限再补充编写粘包问题的解决方案示例吧。
(本文作者原创,除非明确授权禁止转载)
其他鸿蒙网络编程文章:
更多关于HarmonyOS 鸿蒙Next网络编程系列6-TCP数据粘包表现及原因分析的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next网络编程系列6-TCP数据粘包表现及原因分析的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙系统中进行TCP网络编程时,TCP数据粘包现象及其原因分析如下:
TCP数据粘包是指发送方发送的多个数据包在接收方被粘合成一个数据包接收的现象。这通常是由于TCP协议本身的特点导致的,TCP是一个面向流的协议,它不会为每一个发送的数据包设置边界标志。
原因主要有以下几点:
-
TCP缓冲机制:TCP在传输数据时,会先将数据放入缓冲区,当缓冲区中的数据达到一定量时,才会被发送出去。如果发送的数据包较小,且发送速度快,这些数据包可能会被缓冲区合并成一个大的数据包发送。
-
接收方读取策略:接收方在读取数据时,如果一次读取的字节数大于或等于发送方发送的两个数据包的总大小,那么这两个数据包就会被粘合成一个数据包被读取。
-
Nagle算法:Nagle算法是为了减少网络中小数据包的数量而设计的一种算法。它会将小的数据包合并成一个大的数据包发送,以减少网络中的传输次数。这在某种程度上也会加剧数据粘包的现象。
在HarmonyOS鸿蒙系统中进行TCP网络编程时,开发者需要注意TCP数据粘包的问题,并采取相应的措施进行处理,如设置TCP_NODELAY选项禁用Nagle算法,或者在应用层协议中添加数据包边界标志等。
如果问题依旧没法解决请联系官网客服, 官网地址是 https://www.itying.com/category-93-b0.html