引言
TCP(传输控制协议)工作在OSI模型的传输层。OSI模型将计算机网络功能划分为七个层级,从底层到顶层依次是:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。传输层负责在网络节点之间提供可靠的端到端通信,隐藏了底层网络的细节,并提供面向连接或无连接的数据传递服务。
TCP的工作原理和特性
TCP是一种面向连接的、可靠的传输协议,提供数据的可靠性、流量控制、拥塞控制等功能。它通过使用序号、确认和重传机制来确保数据的可靠传输,并支持全双工通信。TCP通过三次握手建立连接,通过四次挥手关闭连接,确保数据的完整性和顺序性。
TCP报文首部
1.源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
2.序号,占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始;
3.确认号,占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
4.数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远;
5.保留,占6位,保留今后使用,但目前应都位0;
6.紧急URG,当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据;
7.确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
8.推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
9.复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
10.同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
11.终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
12.窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受;
13.检验和,占2字节,校验首部和数据这两部分;
14.紧急指针,占2字节,指出本报文段中的紧急数据的字节数;
15.选项,长度可变,定义一些其他的可选的参数。
TCP的三次握手
1. 第一次握手:SYN
客户端希望与服务器建立TCP连接时,会发送一个SYN(同步序列编号)包到服务器。这个包中包含客户端的初始序列号(ISN)。
-
SYN标志位:1
-
序列号:客户端的初始序列号(ISN)
2. 第二次握手:SYN-ACK
服务器收到客户端的SYN包后,会发送一个SYN-ACK包作为响应。这个包中包含服务器的初始序列号和对客户端SYN包的确认。
-
SYN标志位:1
-
ACK标志位:1
-
序列号:服务器的初始序列号(ISN)
-
确认号:客户端的初始序列号 + 1
3. 第三次握手:ACK
客户端收到服务器的SYN-ACK包后,会发送一个ACK包作为确认。这个包中包含对服务器SYN包的确认。
-
ACK标志位:1
-
确认号:服务器的初始序列号 + 1
三次握手的意义
通过三次握手,客户端和服务器确认了彼此的初始序列号,并建立了可靠的连接。这个过程确保了双方都能够接收和发送数据。
TCP的四次挥手
1. 第一次挥手:FIN
当客户端希望终止连接时,会发送一个FIN(结束)包到服务器。
-
FIN标志位:1
2. 第二次挥手:ACK
服务器收到客户端的FIN包后,会发送一个ACK包作为确认。
-
ACK标志位:1
-
确认号:客户端的序列号 + 1
3. 第三次挥手:FIN
服务器在完成数据传输后,会发送一个FIN包到客户端,表示服务器也希望终止连接。
-
FIN标志位:1
4. 第四次挥手:ACK
客户端收到服务器的FIN包后,会发送一个ACK包作为确认。
-
ACK标志位:1
-
确认号:服务器的序列号 + 1
四次挥手的意义
通过四次挥手,客户端和服务器确认了连接的终止。这个过程确保了双方都能够优雅地关闭连接,避免数据丢失。
TCP连接的状态转换
建立连接
-
CLOSED:初始状态,表示没有连接。
-
SYN-SENT:客户端发送SYN包后进入此状态。
-
SYN-RECEIVED:服务器收到SYN包并发送SYN-ACK包后进入此状态。
-
ESTABLISHED:客户端收到SYN-ACK包并发送ACK包后进入此状态,连接建立。
终止连接
-
ESTABLISHED:连接已建立。
-
FIN-WAIT-1:客户端发送FIN包后进入此状态。
-
FIN-WAIT-2:客户端收到服务器的ACK包后进入此状态。
-
CLOSE-WAIT:服务器收到FIN包并发送ACK包后进入此状态。
-
LAST-ACK:服务器发送FIN包后进入此状态。
-
TIME-WAIT:客户端收到FIN包并发送ACK包后进入此状态。
-
CLOSED:连接完全关闭。
⭐为什么客户端最后还要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
⭐为什么TCP一定要三次握手和四次挥手?少一次不行吗?
如果只有两次握手,会出现以下问题:
无法确认客户端的接收能力:
在两次握手中,服务器发送SYN-ACK包后,就认为连接已经建立。但如果客户端的ACK包丢失,服务器并不知道客户端是否真的收到了SYN-ACK包。这会导致服务器认为连接已建立,而客户端认为连接未建立,造成状态不一致。
旧连接的干扰:
如果网络中存在延迟的旧SYN包,服务器可能会误认为这是一个新的连接请求,从而建立错误的连接。三次握手通过客户端的ACK包确认,可以有效避免这种情况。
因此,三次握手是确保连接可靠建立的最小次数。
如果只有三次挥手,会出现以下问题:
数据丢失的风险:
在三次挥手中,服务器在收到客户端的FIN包后,会立即发送FIN-ACK包,表示自己也希望关闭连接。但如果服务器还有未发送完的数据,这些数据可能会丢失。四次挥手允许服务器在确认客户端的FIN包后,继续发送剩余的数据,直到所有数据发送完毕后再发送自己的FIN包。
状态不一致:
如果服务器在收到客户端的FIN包后立即关闭连接,而客户端仍在等待服务器的FIN包,会导致状态不一致。四次挥手通过明确的FIN和ACK交互,确保双方都同意关闭连接。
因此,四次挥手是确保连接可靠关闭的最小次数。
结论
TCP的三次握手和四次挥手是建立和终止连接的关键步骤。通过理解这两个过程,我们可以更好地理解TCP协议的工作原理,并在实际应用中优化网络性能。、