TCP协议

Posted 各种西瓜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP协议相关的知识,希望对你有一定的参考价值。

1.TCP的概念

2.TCP首部格式

TCP协议(1)

TCP的首部包含了20字节的固定部分和长度可变的选项部分。

  • 序号:TCP协议在数据传输的过程中是基于字节流的并且在传输给传输层的时候会将字节流进行分段,序号用来表示这个报文段的第一个字节(报文段的第一个字节号就是序号)。这个序号是由特定的算法生成的随着时间逐渐递增的数字,最大值是2^32-1。这样设计序号主要有三个原因:1. 标识两个主机间前后传输报文段的关系。2.防止由于网络延迟有的分组被重发后,而导致某一方连接做出错误的解释。3.防止黑客TCP劫持。

  • 确认号:是期望收到下个报文段数据的第一个字节号。

  • 首部长度:指出首部长度共有多少4个字节,TCP首部长度可以在20-60个字节之间。

  • 标志位:

    URG : 紧急bit,当URG=1时,代表该报文段有紧急数据应该尽快传输(优先级高)。 ACK : 当ACK=1时代表确认号有效,否则无效。 PUS : 当PUS=1时代表该报文段应当尽快传输给接收应用进程,而不用等待缓存填满。 RST : 当RST=1时代表TCP连接出现了严重差错,必须释放连接然后重新建立。 SYN : 当SYN=1时代表这是一个请求连接或者连接接受报文。 FIN : 当FIN=1时代表报文段的发送端已经发送完数据,并要求释放连接。

  • 窗口:窗口字段用来控制发送方的的发送数据量,接收方根据设置的缓存确定自己接收窗口的大小,然后通知对方以确定对方发送窗口的上限。

  • 校验和:检验部分包括TCP首部和报文段部分,要加上12字节的伪首部。

  • 紧急指针:指出本报文段中紧急数据的最后一个字节的序号,并且URG标志位置为1。

  • 选项:TCP只规定了一种选项,即最大报文段长度MSS(max segment size),MSS会通知发送方我所能接收的报文段的数据字段的最大长度是MSS个字节。

3.建立连接(三次握手)

TCP协议(1)

使用抓包工具来分析TCP连接建立的过程是一个很好的方式,笔者通过连接自己的服务器来分析TCP是如何建立连接的。

  • TCP连接建立流量图


TCP协议(1)

  • 1. 客户端发送一个SYN=1的报文指明要连接服务器的端口,以及初始序号ISN(seq=592986035)这个序号是随着时间而不断变化的每个连接都有不同ISN。此时发送端将执行主动打开(active open)。


    TCP协议(1)

  • 2.服务器将向客户端发送一个SYN=1和ACK=1的包含服务器初始序号ISN(seq=2076924210)的报文段作为应答。同时,将确认序号置为客户端序号加一(Ack=592986036)并执行被动打开(passive open)。


    TCP协议(1)

  • 3.客户端接收到服务器的报文后,会再次发送一个ACK=1的报文段作为应答。此时客户端发送的确认序号是服务端的序号加一(ACK=2076924211)

TCP协议(1)

4.关闭连接(四次挥手)

  • TCP关闭连接流量图

    TCP协议(1)

  • 1.主动关闭方向被动关闭方发送一个FIN=1,ACK=1,以及初始序号(seq=2076924211)和确认号(Ack=592986036)的报文,并执行主动关闭(active close)。

    TCP协议(1)

  • 2.收到主动关闭方的报文后,被动关闭方将会向主动关闭方发送一个ACK=1,以及序号为主动关闭方确认号(seq=592986036)和主动关闭方序号加一的确认号(ACK=2076924212)的报文。此时在主动关闭方到被动关闭方的数据流向停止。

    TCP协议(1)

  • 3.被动关闭方在没有数据向主动关闭方发送的情况下,将会发送一个FIN=1,ACK=1以及序号和确认号都和ACK报文相同的报文。

TCP协议(1)

  • 4.最后主动关闭方向被动关闭方发送一个ACK=1,以及序号(seq=2076924212)和确认号(Ack=592986037)的报文。连接关闭。

5.为什么是四次挥手而不是三次

这是因为TCP连接是全双工的,数据在两个方向上能够同时传递,因此每个方向的数据传输都必须单独关闭。当一端收到FIN并响应给对端的时候,这一方向的数据流便停止了,也就是半关闭。

6.TCP状态机


7.2MSL状态

第一个理由是因为如果主动关闭方(客户端)最终的ACK丢失,那么服务器将会重新发送那个FIN,以允许主动关闭方重新发送那个ACK。要是客户端不维护2MSL状态,那么客户端将会不得不响应一个RST报文段,而服务器将会把它解释为一个错误,导致TCP连接没有办法完成全双工的关闭,而进入半关闭状态。

 第二个理由是假如我们在192.168.1.1:5000和39.106.170.184:6000建立一个TCP连接。一段时间后我们关闭这个连接,再基于相同插口建立一个新的TCP连接。这个新的连接称为前一个连接的化身。老的连接很有可能由于某些原因迟到了,那么新的TCP连接很有可能会将这个迟到的报文认为是这个TCP连接的又一个化身。为了防止这种情况的发生TCP连接必须让TIME_WAIT状态持续两倍的MSL,在此期间将不能基于这个插口建立新的化身,让它有足够的时间使迟到的报文段被丢弃。

8.FIN_WAIT2状态

主动关闭方(客户端)发送了FIN,并且另一端也对它进行了确认。此时主动关闭方将进入FIN_WAIT2状态,另一段进入CLOS_EWAIT状态。接下来只有被动关闭方(服务端)发送FIN完成这个关闭,主动关闭方才能进入TIME_WAIT状态。这意味着主动关闭方有可能会永远保持FIN_WAIT状态。另一段也一直保持在CLOS_EWAIT状态,直到应用层决定关闭这个连接。为了防止这种情况的发生,规定如果主动关闭方的应用层决定执行一个全关闭而不是半关闭的话,就设置一个定时器,如果这个连接空闲10min57s,TCP连接就进入CLOSED状态。

9.平静时间

在主机正常工作的时候,2MSL等待状态不会让这个插口建立新的TCP连接,但是如果在2MSL等待状态的主机出现故障并在MSL秒内启动,那么迟到的报文就会错误的被当作重启后新的连接的报文段,所以规定在TCP启动后的MSL时间内不允许建立任何连接,这个时间被称为平静时间。但是很少的TCP实现遵守这一原则,因为大多数主机重启的时间都大于MSL。


以上是关于TCP协议的主要内容,如果未能解决你的问题,请参考以下文章

分析tcp协议原理

TCP/IP协议

什么是TCP/IP协议?

TCP/IP协议是啥?

Labview(2)之TCP协议

TCP/IP协议