三次握手和四次挥手的各种状态

关于四次挥手

说到四次挥手,可能有些人不知道是什么意思。可是如果说三次握手,应该说大部分学计算机的朋友应该都知道了吧。三次握手,不管是学网络还是学计算机,都应该是必修课之一了,具体是什么概念,在此就不再赘述了。

重新说回四次挥手,其实,四次挥手是三次握手之后的产物。TCP协议中,在发送数据之前,需要进行三次握手的确认,同样的,在取消连接的时候,客户端和服务端同样需要进行确认,而这确认的过程,就是所谓的四次挥手。

四次挥手

图是从网络上周到的关于TCP进行三次握手和四次挥手的过程图。从这可以看出双方的联系。

为什么要关注四次挥手

了解了四次挥手后,可能有人认为get到了一个新的概念了。那么,仅此而已吗?之所以关注四次挥手,其实是因为它更贴近于开发,我们日常的很多编程过程中遇到的网络问题,有一部分,也是来源于四次挥手。所以,了解四次挥手的各种状态,对于开发排错,还是有较大的好处的

三次握手的两种状态

在此先说,在实现四次挥手的各种状态之前,我们能监控到的三次握手的两种状态。

Listening

Listening 是服务器端的状态,通过netstat查看到该状态,说明该PC启动了一个服务端在监听某个端口。要实现这种状态,在Java中只需要开启一个serversocket即可。

ServerSocket serverSocket=new ServerSocket(8080);

当服务器端运行了这样一段代码的时候,通过netstat可以跟踪到的端口状态就是Listening

监听

由于服务器端口号是固定的,同一个端口号只能属于一个程序,所以,通常在这个阶段会遇到的问题,就是端口被占用的问题,Java里面的常见异常就是BindException。

Established

Established 是服务器端和客户端共有的状态,表示双方处于连接状态。通常在这种状态,客户端会开启一个随机端口,与服务器端口进行发送数据,所以在这种状态下,客户端netsstat会发现一条Established的连接是与服务器相连的,端口号随机。而服务器端通过netstat查看,除了原本端口监听的数据连接数据外,同样会发现一条Established的连接与客户端相连。

正常连接

四次挥手的各种状态

上面讲的主要是三次握手的两种状态,接下来讲下四次挥手阶段的几个状态。应该说,在编程过程中,很容易由于编程人员的疏忽,在四次挥手阶段导致各种网络问题

FIN_WAIT_2

为什么不说FIN_WAIT_1,而说FIN_WAIT_2?因为FIN_WAIT_1的状态是在主动方发出close的时候转瞬即逝的状态,不好监控,而且一般不会有问题。

回到最先的那幅图可以看到,FIN_WAIT_2是在主动发出关闭连接请求后的一种状态,此时,客户端还没有发出最后的ACK码。

要重现这种状态,只要无论是在服务器或者是在客户端,主动调起关闭连接的请求而被调用方不进行处理即可。

CLOSE_WAIT

CLOSE_WAIT 与FIN_WAIT_2 是主动与被动的关系,该状态出现在被动关闭连接方。上面说到,一方关闭连接,一方不进行处理,就会导致主动一方进入FIN_WAIT_2状态,而被动方则进入CLOSE_WAIT状态。

CLOSE_WAIT 与FIN_WAIT_2这种两种状态的大量出现,意味着其中有一方没有做好socket关闭的的处理,通常可能出现在客户端和服务器端采用短连接的方式进行数据传输,而其中一方没做好关闭操作的情况下。

值得注意的是,如果是服务端进行了socket关闭而客户端不进行关闭,那么服务器端在进入FIN_WAIT_2状态不久就会进入TIME_WAIT状态。而如果是客户端进行进行socket关闭的时候,客户端会处于FIN_WAIT_2状态知道系统自动处理为止,而服务端则一直处于close_wait状态。

试验代码:
//客户端

for(int i=0;i<49;i++){

Socket socket =new Socket(host,port);

socket.close();

}

//服务端

ServerSocket serverSocket=new ServerSocket(8080);

正常连接

效果如下:

以上方法,会导致大量服务器资源无法释放。。。。

TIME_WAIT

TIME_WAIT 是在四次挥手过程中的最后一步,一般走完四次挥手的正常流程,主动发起关闭连接的一方都会处于这个状态一段时间,具体的时间根据系统而定。在这一步,会遇到的情况就是前面说的,有服务器端发起连接关闭,客户端没有关闭。因为是服务器端进行关闭的,所以进入FIN_WAIT_2状态不久就会进入TIME_WAIT状态。大量的请求关闭导致的服务器出现大量的TIME_WAIT状态从而使服务器无法正常的运行。典型例子:mysql连接未关闭。

至此,三次握手和四次挥手会出现的各种状态总结完毕。以上所述,属个人观点,若有错误,还请批评指正。

Leave a Comment

邮箱地址不会被公开。 必填项已用*标注