(一、)三次握手:
(1)服务器必须准备好接受外来的连接。这通常通过调用socket、bind和listen这三个函数来完成,我们称之为被动打开。
(2)客户端通过调用connect发起主动打开。这导致客户TCP发送一个SYN(同步)字节,它告诉服务器客户将在(待建立)连接发送的数据的初始序列号。通常SYN分节不携带数据,其所在的IP数据报只含有一个IP首部、一个TCP首部及可能有的TCP选项。
(3)服务器必须确认(ACK)客户SYN,同时自己也得发送一个SYN 分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户SYN的ACK确认。
(4)客户必须确认服务器的SYN。
(二.)TCP连接终止:
TCP建立一个连接需3个分节,终止一个连接则需要4个分节。
(1)某个应用进程首先调用close,我们称该端执行主动关闭。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
(2)接收到这个FIN的对端执行被动关闭。这个FIN由TCP确认。它的接收也作为一个文件的结束符传递给接收端应用进程(放在已排队等侯该应用进程接收的任何其他数据之后),因为FIN的接收意味着接收端应用进程在相应连接上再无额外的数据可接收。
(3)一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致的TCP也发送一个FIN。
(4)接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
很多人会问,为什么建链接要3次握手,断链接需要4次挥手?
对于建链接的3次握手,主要是要初始化Sequence Number 的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number(缩写为ISN:Inital Sequence Number)——所以叫SYN,全称Synchronize Sequence Numbers。也就上图中的 x 和 y。这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序(TCP会用这个序号来拼接数据)。
对于4次挥手,其实你仔细看是2次,因为TCP是全双工的,所以,发送方和接收方都需要Fin和Ack。只不过,有一方是被动的,所以看上去就成了所谓的4次挥手。如果两边同时断连接,那就会就进入到CLOSING状态,然后到达TIME_WAIT状态。
(三.)TCP状态转换图:
TIME_WAIT状态存在的两个理由:
(1)可靠的实现TCP全双工连接的终止
(2)允许老的重复分节在网络中消逝
1)TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就会触发被动端重发Fin,一来一去正好2个MSL,2)有足够的时间让这个连接不会跟后面的连接混在一起(你要知道,有些自做主张的路由器会缓存IP数据包,如果连接被重用了,那么这些延迟收到的包就有可能会跟新连接混在一起)。