TCP协议详解

   1.TCP概念

     TCP是一种保障可靠性的传输层协议. 

               这个报文我画的其实有点蠢,书上的更标准,因为TCP底层是位图实现的,一行一个uint更合理.

              

              报文解析:

              源端口,目的端口: 标识唯一进程,socket五元组其二,进程网络通信必备. 0~1023是经典端口,一般不用.1024~65535自己用.

              32位序号,32位确认序号 : 接收方根据序号整理包序,去重和计算ack序号,发送方根据ack序号知道发送的数据已接收,未接收的会重传.实现全双工通信.

              4位首部长度: TCP报文长度 = 首部长度*4  单位:字节   0~60字节

              6位标志位: 标记特殊请求. SYN,FIN,ACK连接管理请求.  PSH催促接收缓冲区处理数据请求. RST重新连接请求(连接异常情况).  URG表示有紧急数据需要处理.

              16位窗口大小: 自己的接收缓冲区剩余空间大小

              16位紧急指针: 标识紧急数据

              16位校验和: TCP报文校验

 

   2.TCP特点

     (1)连接: 在知道对方的ip和port之后,需要建立连接

     (2)可靠: 能感知到对方是否收到消息

     (3)面向字节流: 有读写缓冲区,读写自由

 

     3.可靠性

    (1)连接管理机制 --- 保证双方连接

    

     三次握手: 服务器进入LISTEN状态后,客户端向服务器发送SYN连接请求,服务器收到后回应ACK并发送SYN连接请求,等客户端回应ACK后则连接建立成功。

     四次挥手: 当有一方主动断开连接后,会发送FIN断开请求,被动方则回应ACK并进入CLOSE_WAIT状态,等被动方关闭文件描述符后,会发送FIN断开请求,此时主动断开方处于TIME_WAIT状态并回应

ACK,2MSL后,TCP连接断开。

 

    (2)确认应答(ACK) --- 明确对方是否收到

     

 

     (3)超时重传 --- 解决丢包问题

               

    如果丢包了,在一定时间间隔内没有收到ACK,就会重发数据

    如果ACK丢了,会收到重复的数据,那么可以利用序列号去重

  

 

      (4)流量控制  ---  根据接收方的缓冲区大小决定发送窗口大小

 

  

       1.通过ACK将接受端缓冲区空闲大小放入TCP首部窗口大小字段中;

       2.根据空闲大小决定窗口大小,发送端根据窗口大小决定发送速度;

       3.满了,发送端不发,但定期会发一个窗口探测,接收端回应窗口大小

   

   (5)拥塞控制  ---  根据网络拥堵情况决定发送窗口大小    

    在不清楚网络状态情况下,贸然发送大量数据可能会雪上加霜    

    慢启动机制: 指数增长--> 加法增大 -->(出现丢包) 乘法减小 (轮询)

 

 

     1.发送开始时,拥塞窗口为1,每有一个ACK到达,拥塞窗口+1

     2.实际窗口大小=min(拥塞窗口,流量控制窗口)

     3.慢启动中,拥塞窗口指数增长 --- 拥塞避免算法

 

 

     4.可靠性基础上的效率提升

    (1)滑动窗口 --- 16位窗口大小--->接收端缓冲区大小  不回复ACK允许发送的最大数据量

    发一次数据回一次ACK,效率低.

    一次发送多条数据,能大大提高性能.

               

    窗口大小就是无需等待ACK就可以发送数据的最大值.

            

     发送窗口: (1)没收到ack (2)允许发送还未发送

          接收窗口: 允许接收的

           

        快重传机制:  接收窗口未按序收到

                       

        1.部分ACK丢了 --- 可以通过后续ACK确认

                             

        2.数据包丢了 --- 不必等待超时时间再重传,ACK重复确认三次,告诉发送方,他要的M3,等待发送方重传 --- 之后执行快恢复算法

此时如果收到M3,那么会ACK(下一个是M8),因为之前的数据都被内核放到了接收缓冲区

                           

 

    (2)延迟应答  ---  不急着回复ack,等一会一次性多读点数据,让接收窗口更大

      

 

    (3)捎带应答 ---  ack和数据一起发

                      

 

 

   5.粘包问题

     出现原因: tcp协议每次只会取出小于等于mss大小的数据进行传输 --- 防止了ip分包

             解决方法: 制造数据边界 ---  (1)报文结尾使用分隔符 (2)指定报文长度

   

        6.TCP保活机制  --- 连接异常

            出现原因: 停电断网,电脑关了,对端还在连接,浪费资源

            解决方法: 长时间没收到响应的时候,发送心跳包,多次发送后,对方没响应,则断开连接.

            心跳包实现: (1)应用层自己实现 (2)启用tcp的keepalive保活机制 

         

         7.优雅的关闭TCP连接

              双方使用shutdown()关闭写端.

              

 

 

    

    

           

 

posted @ 2020-10-30 19:52  Duikerdd  阅读(355)  评论(0编辑  收藏  举报