您当前的位置:首页 > 电脑百科 > 网络技术 > 网络技术

TCP粘包的解决方案

时间:2020-05-25 13:41:53  来源:  作者:

基本概念

  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);
  •  
  • 如以上代码所示,发送和接收就直接调用socketAPI接口就可以了。这样写简单,但是有如下问题:容易阻塞主进程,引起多余的进程调度和不可控的系统超时;可以用独立的进程或者线程来优化,但会引起复杂的同步逻辑;无法适应大规模的发送端和接收端同时工作的场景。
  • 无阻塞的发送和接收: 这种方式编码复杂一点,但是解决了阻塞方式引起的问题,是目前的主流解决方案。发送端的流程图是这样的:Alice 固定长度法发送端流程图说明如下:流程图中假设发送的预设固定长度是1024个字节。如果利用EPOLL的Level方式,应该在EPOLLOUT的回调函数中调用alice_send_data,隐式实现3->4->3的循环流程。如果利用EPOLL的Edge方式,应该在EPOLLOUT的回调函数中调用alice_send_epoll,显式实现3-4-3的循环流程。伪代码是这样的:
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);
   }

 

  •  
  • 接收端的流程图是这样的:Bob 固定长度法接收端流程图我们可以看出,接收部分可发送部分很相似,这样本文就不重复代码了。

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

TCP粘包的解决方案

 

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

  • 发送端知道发送数据的实际长度,然后加上记录长度的4个字节,算出数据总长,按照固定长度的办法发送。
  • 接收端则需要动态获得数据的实际长度,它的流程图是这样的:Bob 变长法接收端流程图

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

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

TCP粘包的解决方案

 

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

  • 发送端可以按照固定长度的办法发送。
  • 接收端则需要不断地查找接收缓冲里面的所有数据,看是否有特殊字符串的存在。它的流程图是这样的:Bob 特殊字符串接收端流程图


Tags:TCP粘包   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采...【详细内容】
2020-05-29  Tags: TCP粘包  点击:(53)  评论:(0)  加入收藏
基本概念 TCP本质上是数据流,从原理上看,没有包的概念,TCP包对应用程序员可以是透明的。 粘包实际上是把底层包的实现和上层流的概念混在一起。 粘包问题本质上是如何确定数据...【详细内容】
2020-05-25  Tags: TCP粘包  点击:(97)  评论:(0)  加入收藏
TCP是个“流”协议,所谓流,就是没有界限的一串数据。可以想想河里的流水,是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况...【详细内容】
2019-08-28  Tags: TCP粘包  点击:(213)  评论:(0)  加入收藏
▌简易百科推荐
写一个shell获取本机ip地址、网关地址以及dns信息。经常会遇到取本机ip、网关、dns地址,windows一个命令ipconfig /all全部获取到,但linux系统却并非如此。linux系统都自带ifc...【详细内容】
2021-12-27  K佬食古    Tags:shell   点击:(2)  评论:(0)  加入收藏
步骤1、配置 /etc/sysconfig/network-scripts/ifcfg-eth0 里的文件。it动力的CentOS下的ifcfg-eth0的配置详情:[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifc...【详细内容】
2021-12-24  忆梦如风    Tags:网卡   点击:(10)  评论:(0)  加入收藏
1、查找当前目录下所有以.tar结尾的文件然后移动到指定目录find . -name “*.tar” -execmv {}./backup/ ;注解:find &ndash;name 主要用于查找某个文件名字,-exec 、xargs可...【详细内容】
2021-12-17  郭主任    Tags:运维   点击:(20)  评论:(0)  加入收藏
对于经常上网的朋友来说,除了手机购物上网,pc端玩网页游戏还是很多小伙伴首选的,但是有时候明明宽带链接上了,打开浏览器却出现上不了网的现象,下面小编要来跟大家说说电脑有网络...【详细内容】
2021-12-16  小白系统    Tags:网页无法打开   点击:(28)  评论:(0)  加入收藏
在访问像github、gitlab这样的外国网站时,很有可能会出现页面加载不出来或找不到页面的错误。这时候有的朋友就会以为是网络的问题,于是把Wifi断掉连上自己手机的热点,结果却还...【详细内容】
2021-12-15  启施技术IT狼叔    Tags:外网   点击:(16)  评论:(0)  加入收藏
网络地址来源:获取公网IP地址 https://ipip.yy.com/get_ip_info.phphttp://pv.sohu.com/cityjson?ie=utf-8http://www.ip168.com/json.do?view=myipaddress...【详细内容】
2021-12-15  韦廷华12    Tags:外网ip   点击:(15)  评论:(0)  加入收藏
准备好软件IPOP、用ENSP模拟一下华为交换机 启动交换机 <Huawei>sysEnter system view, return user view with Ctrl+Z.[Huawei]sysname FTPClient[FTPClient]interface vla...【详细内容】
2021-12-15  思源Edward    Tags:交换机   点击:(24)  评论:(0)  加入收藏
我们经常用到netstat命令查看主机连接状况,包括连接ip、端口、状态等,今天就练习下shell分析netsat结果。描述假设netstat命令运行的结果我们存储在nowcoder.txt里,格式如下:Pro...【详细内容】
2021-12-14  K佬食古    Tags:netstat   点击:(19)  评论:(0)  加入收藏
什么是滑动窗口?窗口是操作系统开辟的一块缓存空间,发送方在收到接收方ACK应答之前,必须在缓冲区保留已发送的数据,如果按期收到确认应答,数据就可以从缓冲区移除。什么是滑动窗...【详细内容】
2021-12-14  DifferentJava    Tags:TCP   点击:(30)  评论:(0)  加入收藏
概述日常管理华为路由设备过程中,难为会忘记设备登录密码,那么该如何重置设备登录密码吗?本期文章将全面向各位小伙伴总结分享。重置华为设备登录密码思路先行 采用console登录...【详细内容】
2021-12-10  onme0    Tags:   点击:(27)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条