TCP协议

  • TCP协议介绍
    tcp协议是面向连接的,在传输数据前会先建立一条连接,互联网络与单个网络有很大的不同,因为互联网络的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其他参数。能够动态地适应互联网络的这些特性,而且具备面对各种故障时的健壮性

TCP包头格式

 |     源端口号(16位)            |            目的端口号(16位)           |

 |                           序号(32位)                                   |

 |                         确认序号(32位)                                 |

 |首部长度(4位)   |  保留(6位) |URG|ACK|PST|SYN|FIN|   窗口大小(16位)    |
 |       校验和(16位)          |             紧急指针(16位)               |

 |                            选项                                         |
 
 |                            数据                                         |
  • 源端口号和目的端口号:分别表示本地主机使用的端口号和应该发给目的主机的端口号。
  • 序号:包的顺序编号,使包的传输能有顺序。
  • 确认序号:目的主机收到数据后发给本地主机的确认编号。使包在传输过程中尽量避免丢失。
  • 首部长度: TCP首部长度最大15*4(字节)=60字节,其中标准长度为20字节(不包含选项)
  • 6个标志位:
    1. URG:紧急指针标志位 ,表示紧急指针是否有效
    2. ACK:确认标志位,表示确认序号是否有效。
    3. PSH:提示接收端的应用程序立刻从TCP缓冲区中把数据拿走。
    4. RST:重置标志位,表示对方要求重新建立连接。把携带该标志位的称为复位报文段
    5. SYN:同步标志位,表示对方请求建立连接,把携带标志位的称为同步报文段。
    6. FIN:结束标志位,通知对方“我”要关闭了,把携带该标志位的称为结束报文段。
  • 窗口大小:TCP有自己的缓冲窗口,主要用来做做流量控制,通信双方各声明一个窗口,标识自己当前能够的处理能力。
  • 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的校验和不光包含TCP的首部,还包含数据部分。
  • 16位紧急指针:区分紧急数据,TCP有字节序,可以允许一部分有序的字节先发送。

TCP三次握手

  • 大致思想
    1. 客户端给服务器发一条消息,服务器收到,服务器知道了客户端能 正常发送消息。
    2. 然后服务器给客户端一个应答,客户端收到后,知道了自己能正常发送消息,也能正常接收服务器的消息。
    3. 最后客户端在发给服务器一个消息,服务器收到后,知道了客户端能正常接受消息,自己也能正常发送消息。
    4. 3次握手主要为了让客户端和服务器都知道自己和对方的发送能力和接受能力都是正常的。
  • 具体过程

    一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态。客户端收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了。服务端收到 ACK 的 ACK 之后,处于 ESTABLISHED 状态,因为它也一发一收了。

TCP四次挥手

  • 大致思想
    客户端先告知服务器想断开连接,服务器收到后对客户端发送应答,确保自己收到消息,接着服务器会再发一条消息表示自己也要断开连接。客户端收到后向服务器发送应答。这时服务器和客户端都知道了要断开连接。
  • 具体过程
  1. 客户端发送一个报文给服务端(没有数据),其中FIN设置为1,Sequence Number置为p,客户端进入FIN_WAIT_1状态
  2. 服务端收到来自客户端的请求,发送一个ACK给客户端,Acknowledge置为p+1,服务端年进入CLOSE_WAIT状态
  3. 服务端发送一个FIN给客户端,ACK置为1,Sequence置为q,Acknowledge置为p+1,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态
  4. 客户端收到FIN后,进入TIME_WAIT状态,接着发送一个ACK给服务端,Acknowledge置为q+1,最后客户端和服务端都进入CLOSED状态
TCP状态机

  • TCP_CLOSE:关闭状态, 一个新建的TCP socket 会处于该状态。

  • TCP_LISTEN: 监听状态,一般服务器端套接字在调用Listen系统调用后即处于该状态。

  • TCP_SYN_SENT:同步信号已经发送状态,这个状态一般是指客户端发送SYN(建立连接的同步)数据包后所处的状态(tcp三次握手的第一个包)。在接收到远端服务器端的应答后,即从该状态进入TCP_ESTABLISHED状态。

  • TCP_SYN_RECEIVED:同步信号已经接受状态,服务器端在接受到远端客户端SYN数据包后,进行相应的处理(创建通信套接字等),然后发送应答数据包(tcp三次握手的第二个包),并将新创建的通信套接字状态设置为TCP_SYN_RECEIVED,在接受到客户端的应答后,即进入TCP_ESTABLISED状态。

  • TCP_ESTABLISED:建立连接状态,这是双方进行正常通信所处的状态。

  • TCP_FIN_WAIT_1:本地发送FIN(用于结束连接的)数据包后即可进入该状态,等待对方的应答。一般一端发送完其所要发送的数据后,即可发送FIN数据包,此时发送通道被关闭,但仍可继续接受远端发送的数据包。在接受到远端发送的对于FIN数据包的应答后,将进入TCP_FIN_WAIT_2状态。

  • TCP_FIN_WAIT_2:进入该状态表示本地已经接受到远端发送的对于本地之前发送的FIN数据包的应答。进入该状态后,本地仍然可以继续接受远端发送给本地的数据包。在接受到远端发送的FIN数据包后(表示远端也已经发送完数据),本地将发送一个应答数据包,并进入TCP_TIME_WAIT状态。TCP_TIME_WAIT状态存在的时间被称为2MSL时间,这一方面是为避免本地发送的应答数据包丢失,另一方面避免一个新创建的套接字接收到旧套接字中遗留的数据包。

  • TCP_TIME_WAIT:该转状态被称为2MSL等待状态。如果在此期间接收到远端发送的FIN数据包,则表示之前在TCP_FIN_WAIT_2状态发送的ACK应答数据包在传输中丢失或者长时间被延迟,从而造成了远端重新发送了FIN数据包,此时重复ACK应答数据包。一旦2MSL时间到期,则将进入TCP_CLOSED状态,即完成关闭操作。

  • TCP_CLOSE_WAIT:该状态存在于后关闭的一端。当接收到远端发送的FIN数据包后,本地发送一个ACK应答数据包,并将该套接字状态从TCP_ESTABLISED设置为TCP_CLOSE_WAIT。本地可以继续向远端发送数据包,在发送完所有的数据后,本地将发送一个FIN数据包关闭本地发送通道,并将状态设置为TCP_LAST_ACK状态,等待远端对FIN数据包的应答数据包。

  • TCP_CLOSING:如果通信双方同时发送FIN数据包,则同时进行关闭操作,则双方将同时进入TCP_CLOSING状态。具体的,本地发送一个FIN数据包以结束本地数据包发送,如果在等待应答期间,接收到远端发送的FIN数据包,则本地将状态设置为TCP_CLOSING状态。在接收到应答后,再继续装入到TCP_CLOSE_WAIT状态。

  • TCP_LAST_ACK:作为后关闭的一方,在发送FIN数据包后,即进入TCP_LAST_ACK状态。此时等待远端发送应答数据包,在接收到应答数据包后,即完成关闭操作,进入TCP_CLOSE状态

TCP发包问题

  • 累计确认
    TCP协议数据再传输的过程中都是一个包一个包进行传输。每一个包都有一个ID,用ID的方式可以保证不丢包,也可以控制包的顺序。接收端收到包后,会在包头的确认序号写上自己要接受下一个包的序号。
流量控制
接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。当接收方处理好数据,接受窗口 win > 0 时,接收方发个通知报文去通知发送方,告诉他可以继续发送数据了。当发送方收到窗口大于0的报文时,就继续发送数据。如果发送方长时间接受不到这个报文时,双方会陷入一种僵局。为了解决这种问题,当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器。
拥塞控制
  • 流量控制主要是针对发送端和接收端数据的传输量,拥塞控制针对的是双方发送数据的速度。
  • 一条 TCP 连接开始,cwnd 设置为一个报文段,一次只能发送一个;当收到这一个确认的时候,cwnd 加一,于是一次能够发送两个;当这两个的确认到来的时候,每个确认 cwnd 加一,两个确认 cwnd 加二,于是一次能够发送四个;当这四个的确认到来的时候,每个确认 cwnd 加一,四个确认 cwnd 加四,于是一次能够发送八个。可以看出这是指数性的增长。TCP有一个值 ssthresh 为 65535 个字节,当超过这个值的时候,每收到一个确认后,cwnd 增加 1/cwnd,,变成了线性增长。
  • 当出现丢包问题时需要超时重传,这个时候,将 sshresh 设为 cwnd/2,将 cwnd 设为 1,重新开始慢启动。
  • 快速重传算法。当接收端发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速的重传,不必等待超时再重传。TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,cwnd 减半为 cwnd/2,然后 sshthresh = cwnd,当三个包返回的时候,cwnd = sshthresh + 3还在比较高的值,呈线性增长。

posted @ 2021-04-19 15:23  月下繁星杨  阅读(164)  评论(0编辑  收藏  举报