状态说明:
CLOSED:表示初始状态
LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接受连接了
SYN_RCVD:表示接受到了SYN报文,在正常情况下,这个状态是服务器SOCKET建立TCP连接的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat很难看到这个状态,除非写一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不发送因此这个状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态
ESTABLISHED:表示连接已经建立了
FIN_WAIT_1:1和2真正的含义是表示等待对方的FIN报文,而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHE态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WATI_1状态,而当对方回应ACK报文后则进入到FIN_WAIT_2状态,当然在实际正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态比较难见,而FIN_WAIT_2状态还有时常可以用netstat看到
FIN_WAIT_2:FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据要传送给你稍后再关闭连接
TIME_WAIT:表示收到了对方的FIN报文,并发送出ACK报文,就等2MSL后即可回到CLOSED可用状态了,如果FIN_WAID_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态
CLOSING:这种状态比较特殊,实际情况中很少见。正常情况下,发送FIN报文后,按理来说应该先收到(或同时收到)到方的ACK报文再收到对方的FIN报文,但是CLOSING状态表示你发送FIN报文后,并没有收到的收到对方的ACK报文,反而却也收到了对方的FIN报文。发生的原因:如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接
CLOSE_WAIT:表示等待关闭,当对方close一个SOCKET后发送FIN报文给自己,系统毫无疑问也会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态,接下来,实际上真正要考虑的是看你是否还有数据发送给对方,如果没有的各话,那么你也可以close这个SOCKET,发送FIN报文给对方,也即关闭连接,所以你有CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接
LAST_ACK:表示被动关闭一方在发送FIN报文后,最后等待对方的ACK报文,当收到ACK报文后,也即可以进入到CLOSED可用状态了
1.为什么建立协议是三次握手,而关闭连接却是四次握手呢?
因为服务器端的LISTEN状态下的SOCKET当收到SYN报文建连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文时发送。但是关闭连接,当收到对应FIN报文通知时,它仅仅表示对方没有数据发送给你了,但未必你所有的数据都全部发送给对方了,所以你可以未必马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方表示同间现在可以关闭连接了,所以这里的ACK报文和FIN报文多数情况下都是分开发送的
2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
因为虽然对方同间关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISHED状态)但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文人一定被双方收到,因此处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来生发可能丢失的ACK报文
建立连接协议(三次握手)
(1) 客户端发送一个带SYN标志的TCP报文到服务器,这是三次握手过程中的报文1
(2) 服务器端回应客户端的,这是三次握手中的第二个报文,这个报文同时带ACK标志和SYN标志,因此它表示对客户端SYN报文回应
同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯
(3)客户必须再次回应服务段一个ACK报文,这是报文段3
连接终止协议(四次断开)
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一下FIN只意味这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方执行关闭,而
另一方执行被动关闭
(1) TCP客户端发送一个FIN,用来关闭客户端到服务器的数据传送(报文段4)
(2) 服务器收到这个FIN,这它发回一个ACK,确认序号为收到序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号
(3) 服务器关闭客户端连接,发送一个FIN给客户端(报文段6)
(4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)