<返回更多

TCP粘包的解决方案

2020-05-25    
加入收藏

基本概念

  1. TCP本质上是数据流,从原理上看,没有包的概念,TCP包对应用程序员可以是透明的。
  2. 粘包实际上是把底层包的实现和上层流的概念混在一起。
  3. 粘包问题本质上是如何确定数据流的边界。

确定边界的几种典型办法

1. 固定长度法:一般在简单的私有协议中实现,可以简化流程,方便实现。

TCP粘包的解决方案

 

通讯之前先通过第三方规定本次发送的包长

发送:send(fd, wr_data_buf, wr_data_len, 0); /* wr_data_buf 数据缓存, wr_data_len预先设定的固定长度 */
接收:recv(fd, wr_data_buf, wr_data_len, 0);
static int alice_send_data(int fd, char *wr_data_buf)
   {
       int n;
       n = send(fd, wr_data_buf + offset, 1024 - off, MSG_DONTWAIT); /* 无阻塞发送了n个字节*/
       if (n < 0) {
           if (errno == EAGAIN || errno == EINTR)
               return 0;
           else {
                   return -1; /* error */
           }
       } else if (n == 0) {
               return 1; /* socket close */
       }
       offset += n; /*记住总共发了off个字节 */
       if (off < 1024)  /*如果小于预先给定的长度,返回0,继续调用本函数发送 */
           return 0;
       return 1; /*发完了,返回1,继续下面的工作 */
   }

   static int alice_send_epoll(int fd, char *wr_data_buf) /* edge 方式 */
   {
       int offset = 0;
       int finish;
       
       do {
           finish = alice_send_data(fd, wr_data_buf)
       } while (!finish);
   }

 

2. 变长法: 在私有和公共协议中实现,比固定长度法稍微复杂一点,但比较灵活:

TCP粘包的解决方案

 

通讯之前先通过第三方规定长度的位置,以便接收端获取

我们看出,变长法在接收端实际上是两步固定长度法,所以它比固定长度法复杂。但是由于发送端可以灵活的指定数据的长度,也就是每次发送的数据可以不同,应用更加广泛。

3. 特殊字符串法:在私有和公共协议中实现,比变长法更复杂,但是节省包头长度字段,处理更加灵活。

TCP粘包的解决方案

 

通讯之前通过第三方规定一个特殊的字符串,比如说'rnrn',接收端才能据此确定数据流的边界。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>