TCP协议的相关特性

一、定义及原理

TCP协议,传输控制协议,即对数据在传输过程中进行一个详细的控制。

TCP协议段格式:

1、16位的源端口号:要发送数据的进程的端口号;

2、16位的目的端口号:要发送到的目标进程端口号;

3、32位的序列号/32位确认序列号:为了满足全双工的安全机制而存在的,它有以下四个功能:

      1)保证基本的可靠性   2)是数据可以按序到达
      3)支持超时重传          4)高效
4、4位的首部长度:表示该TCP头部有多少个32位bit,即就是有多少个4字节,TCP头部最大长度15*4=60;
5、6位的保留位:以备不时之需
6、6位标志位:
       URG:               紧急指针标志位,紧急指针是否有效
       ACK:                确认应答标志位,
       PSH:                推送标志位,催促接收端把接收缓冲区的数据赶紧处理了
       RST:                 重置标志位,请求重新建立连接
       SYN:                同步标志位,请求建立连接
       FIN:                  结束标志位,通知对方,我要断开连接了
7、16位的窗口大小:表示服务器端能接收多少数据,里面填写的也就是接收缓冲区的大小
8、16位的检验和:由发送端填充,CRC校验,若接收端校验不通过就说明数据有问题
9、16位的紧急指针:标示那部分的数据是紧急数据,需要优先处理

二、TCP的相关特性(机制)
 

 1、确认应答机制:

       如上图所示,左边的客户端应用层向服务器发送数据后,服务器会给客户端返回一个ACK应答,这样客户端才会确认服务器收到了你的数据;

       TCP将每个字节的数据都进行了编号。即为序列号。每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开 始发。

       体现了可靠传输,可靠传输和下面的有连接不相关(无连接也可形成可靠传输,如钉钉)

 2、超时重传机制:

     A给B发送数据,在发送的过程中丢包了(网络拥堵,B处断网等),或是到达B处了,但是B在返回ACK的过程丢包了(即A无法确认B是否收到数据),在一段时间后,A就会重新发送数据。

     在上述第二种情况下,B会重复收到多组数据,并且把这些数据放入缓冲区中,那么我们就可以利用前面提的序列号,从而对比,达到去重的效果。

     那么,如果超时的时间如何确定?TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。

 3.连接管理机制(重要)

       三次握手建立连接,四次挥手断开连接;

       1)所谓三次挥手,实际上是“四次”交互,通信双方各自要向对方发起一个syn(建立连接)的请求,同时还要回应一个ACK,但是中间两次交互,是强制合成一次交互的,即接收方向发送方回应SYN+ACK。

             三次挥手的另一个作用验证双方各自的发送能力和接受能力正常,一定程度上保证了TCP传输的可靠性。因为TCP是有连接的,所以能建立连接,才有的三次挥手,不是三次挥手体现的有连接。

             当然在握手的过程中,双方就此可协调一些重要的参数。

       2)四次挥手中的“挥手”和“握手”一样都是形象的叫法,都是客户端服务器之间的数据交互,都是通信双方各自向对方发起一个断开连接的请求,在各自给对方一个回应。

             当然,为什么是四次?不像握手那样是“三次”?握手中间两次必须合并是因为那两次是同一时机,是在纯内核中完成的,应用程序感知不到,无法干预(内核收到SYN后,会立即返回ACK,并立即发送SYN); 而挥手的FIN的发起不是内核控制的,而是由应用程序调用socket的close方法,才会触发FIN,服务器收到FIN后由内核控制立即回应ACK, 而服务器的FIN需要在服务器的应用程序中执行对应的close方法才会触发,故而中间的ACK和FIN可能会隔一个时间差(当然如果服务器接受到对方的FIN后,应用程序没有多余的操作,直接close,那也会合并ACK和FIN)

        3)

           为什么在挥手中存在几个wait的TCP状态,最后一次的 wait的状态是否没有必要?

            因为在握手和挥手的过程中,同样是会存在超时重传的,如果最后一个ACK丢包了,站在服务器的角度看,此时无法预知,以为是自己的FIN丢包了,就会重新发送FIN,这样就需要客户端重新回应,倘若此时没有wait而是直接close,这样就无法回应,因此利用TIME_WAIT状态保留一段时间,防止ACK丢包情况;

             如果最后一个ACK丢包了,而服务器重传的FIN也丢包了,客户端等的时间到了,也会彻底释放;

             TIME_WAIT的时间会保持2MSL,MSL指的是互联网上两个节点之间,数据传输损耗的最大时间,通常情况下,1MSL = 1min;

 4、滑动窗口

          以上三个机制保证了TCP的可靠性,但是在这基础之上,传输效率又有了折扣,故而引入滑动窗口来补救,(UDP不考虑可靠性,TCP无论怎样补救效率永远也赶不上);

          滑动窗口本质上是减少了等待ACK消耗的时间,(IO操作时主要的消耗就在等待的时间上)即批量发送,批量等待;

                       

          基本的确认应答是,每次发送一个数据就要等一个ACK;

          滑动窗口是不等待的发送一组数据,这一组数据的最大数量,称为“窗口大小”(如图为4000);

          等发送完窗口大小数量的数据后,就需要等待ACK了,等一条发一条;

          如果中间有条ACK丢包了,但后面序号的ACK到达,那么发送方就默认前面的ACK就都收到了

           如果中间的数据丢包了,比如1001-2000丢了,那么这组返回的ACK就会一直是1001前面的序号,等于说服务器向客户端一直索要1001-2000的数据,那么客户端也会意识到问题进行重传,待服务器接受到丢失的数据,缓冲区进行序号重排,才会索要下一组数据;(快速重传,只传送丢包的数据)

 5、流量控制(干预发送窗口大小的机制)

             滑动窗口越大,传输的效率就越高,可靠性会受到影响,系统资源的消耗量就会变大,接受方处理难度增加。故而流量控制就是要根据接收方的处理能力(缓冲区的剩余大小),协调发送方的发送速率;

              当报文是ACK的时候,TCP报头中的16位窗口大小里存储缓冲区的剩余大小,从而回应发送方,这里有两点注意:

                     1)窗口大小是动态的,因为缓冲区的剩余大小也不是固定的,当窗口大小为0时,发送方要暂停发送,暂停发送等待的过程中,会给接收方定期发送窗口探测报文,这个报文不携带具体的业务数据,只是为了触发ACK查询窗口大小;

                      2)窗口最大也不是64Kb,若是缓冲区剩余大小大于64Kb,TCP会在选项部分引入窗口扩展因子,(扩展因子里写了个2,64<<2 = 256)。

6、拥塞控制

        第五点流量控制是考虑到接受方的处理能力来反馈,调整发送方发送数据的能力;

        而这里的拥塞控制的考虑的中间节点的传输数据的处理能力;

        流量控制和拥塞控制共同决定着发送方的窗口大小。(木桶理论,处理能力最差的那个节点决定着中间所有节点的传输能力)。

        由于传输过程中中间节点的最差处理能力没办法直接量化,于是通过拥塞控制在危险的边缘实验,一步步探测来找到一个合适的窗口大小(合适的发送速率)

 7、延时应答

      ——在滑动窗口的基础之上再提升点效率

 

      在接收方收到一定的数据后,延时返回ACK,等待的时间里让接受方把缓冲区的数据提出一些,这样缓冲区的剩余空间就会变大,返回的ACK回应的窗口大小就会变大,下一轮发送的数据就会变得更多。

 8、捎带应答

       ——同样是提高效率

       服务器客户端,最经典的模型就是一问一答;在传输数据的过程中,客户端会捎带问个问题什么的,内核应立即返回ACK,由于TCP存在延时应答,就导致再等待ACK的过程中,服务器给客户端发送业务数据了,并让业务数据捎上这个ACK一起;

  9、面向字节流的粘包问题

          首先要明确,粘包问题中的 "包" ,是指的应用层的数据包。

          在TCP的协议头中,没有如同UDP一样的 "报文长度" 这样的字段,但是有一个序号这样的字段。

          站在传输层的角度,TCP是一个一个报文过来的。按照序号排好序放在缓冲区中。

          站在应用层的角度,看到的只是一串连续的字节数据。

          那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分,是一个 完整的应用层数据包。

       解决方法:应用层约定好应用层协议,明确好应层数据报和数据报之间的界限就好;

                        1)约定好分隔符(如\n);

                        2)约定好每个包的长度;

 

            

 10、异常情况

         传输过程中出现了不可抗力

          正常断开:1.进程崩溃了  2.主机正常流程关机

                             {进程无,对应PCB无,对应的文件描述符释放,执行Close,内核完成四次挥   手,正常断开,而正常关机就是先杀进程}

           非正常断开:1.主机断电   2.网线断开

                               {接受方掉电,发送方会继续发送数据,等待ACK,然后超时重传,重传几次没有应答则自动尝试TCP连接,连接不到就会自动放弃连接,然后单方面断开}

                               {发送方掉电,接受方不知道情况会先等一定的时间,然后会周期性的给发送方发送一个“心跳包”(保活机制),来确认对方是否正常工作,一定周期后,接受方会单方面断开连接}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值