什么是TCP协议?
-
TCP即传输控制协议,是一种面向连接、可靠的基于字节流的通信协议,数据在传输前要建立连接,传输完毕后需要断开连接。
-
客户端在收发数据前要使用connect()函数和服务器建立连接,目的是保证IP、端口、链路等准确无误,为数据的安全传输开辟通道
TCP数据包结构
-
序号:seq(Sequence Number)占32bit,用来表示客户端发送到服务器的数据包的序号,计算机发送数据时对此进行标记。
-
确认号:Ack(Acknowledge Number)占32bit,客户端和服务器端口可以发送,ACK=seq+1
-
标志位:每个标志位占用1bit,共6个,分别为URG、ACK、PSH、RST、SYN、FIN。含义如下:
-
URG:紧急指针有效
-
ACK:确认序号有效
-
PSH:表示接收放应该尽快将这个报文交给应用层
-
RST:重置连接
-
SYN:建立一个新连接
-
FIN:断开一个连接
三次握手的具体过程
握手之前:
客户端和服务器双方都处于CLOSED状态,等待握手包的发出。主动打开连接的为客户端,被动打开连接的是服务器。
第一次握手:
客户端向服务器发出连接请求报文,报文头部中的SYN=1,表示建立一个新连接,并产生seq=x的随机值。此时,客户端进入SYN-SENT状态(同步已发送状态)。
第二次握手:
服务器端接收到了客户端的请求报文后,回复确认报文,报文中syn和ACK(确认序号有效位)都为1,并产生seq=y的随机值,ack=x+1的数据包,并进入SYN-RCVD状态,同步收到状态。
第三次握手:
客户端收到服务器的确认报文后,向服务器回复确认报文,报文中ACK(确认号有效位)为1,ack=y+1,seq=x+1,此时双方进入ESTABLISHED状态,可以开始传输数据。
四次挥手的具体过程
挥手之前
双方都处于ESTABLISHED状态,客户端主动关闭,服务器端被动关闭。
第一次挥手:
客户端发出连接释放报文,并且停止发送数据包。报文头部中FIN=1,表示断开一个连接,seq=u(等于前面已经传过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1状态。
第二次挥手:
服务器端接收到连接释放报文后,发出确认报文,ACK(确认号有效位)为1,ack=u+1,并产生seq=v的随机值,此时,服务器端进入了CLOSE-WAIT状态。
第三次挥手:
客户端接收到服务器端发送的确认报文后,进入FIN-WAIT-2状态,等待服务器端发出的连接释放报文。服务器端将最后的数据报文处理完毕后,向客户端发送连接释放报文,报文头部中FIN=1,表示断开一个连接,ACK(确认号有效位)为1,seq=w的随机值和ack=u+1,此时服务器端进入LAST-ACK状态,等待客户端的确认。
第四次挥手:
客户端收到服务器端的连接释放报文后,发出确认报文,ACK(确认序号有效位)为1,ack=w+1,seq=u+1,此时,客户端进入TIME-WAIT状态,但此时TCP连接还未终止,需等待2MSL(最长报文寿命),当客户端撤销相应的TCB后,客户端进入CLOSED状态。服务器端接收到确认报文后,会立即进入ClOSED状态,此时,TCP连接才算完全断开,四次挥手成功。
为什么客户端要等待2MSL
主要原因是为了保证客户端发送那个的第一个ACK报文能到到服务器,因为这个ACK报文可能丢失,并且2MSL是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃,这样新的连接中不会出现旧连接的请求报文。
问题总结
为什么是三次握手、四次挥手
因为当关闭连接时,服务器端可能不会立即关闭SOOKET,只能通过先回复确认报文的方式应答客户端,等到服务器端所有的报文都处理完毕后,再发送连接释放报文。
我的理解
我认为三次握手中,还可以确认服务器端和客户端的收发能力。