zoukankan      html  css  js  c++  java
  • 关于Socket通讯中的Close_wait状态

    关于Socket通讯中的Close_wait状态

    / 编辑

    编者按:使用Socket通讯,有时我们查看端口状态的时候,经常会发现Socket处于close_wait状态,从而影响系统性能,此文或许会给你一些答案。

    最近遇到的一个关于socket.close的问题,在某个应用服务器出现的状况(执行netstat -np | grep tcp): 

    tcp        0      0 10.224.122.16:50158         10.224.112.58:8788          CLOSE_WAIT

    tcp        0      0 10.224.122.16:37655         10.224.112.58:8788          CLOSE_WAIT

    tcp        1      0 127.0.0.1:32713             127.0.0.1:8080              CLOSE_WAIT

    tcp       38      0 10.224.122.16:34538         10.224.125.42:443           CLOSE_WAIT

    tcp       38      0 10.224.122.16:33394         10.224.125.42:443           CLOSE_WAIT

    tcp        1      0 10.224.122.16:18882         10.224.125.10:80            CLOSE_WAIT

    tcp        1      0 10.224.122.16:18637         10.224.125.10:80            CLOSE_WAIT

    tcp        1      0 10.224.122.16:19655         10.224.125.12:80            CLOSE_WAIT

    ........................................

     

    总共出现了200CLOSE_WAITsocket.而且这些socket长时间得不到释放.下面我们来看看为什么会出现这种大量socketCLOSE_WAIT情况

     

    首先我们要搞清楚的是,这个socket是谁发起的,我们可以看到122.16这台机器开了很多端口,而且端口号都很大,125.12 或者125.10上的端口都是很常见服务器端口,所以122.16上这么多CLOSE_WAIT

    socket是由122.16开启的,换句话说这台机器是传统的客户端,它会主动的请求其他机器的服务端口.

     

    要搞清楚为什么会出现CLOSE_WAIT,那么首先我们必须要清楚CLOSE_WAIT的机制和原理.

     

    假设我们有一个client, 一个server.

     

    client主动发起一个socket.close()这个时候对应TCP来说,会发生什么事情呢?如下图所示.

     

     

     

    client首先发送一个FIN信号给server, 这个时候client变成了FIN_WAIT_1的状态, server端收到FIN之后,返回ACK,然后server端的状态变成了CLOSE_WAIT.

    接着server端需要发送一个FINclient,然后server端的状态变成了LAST_ACK,接着client返回一个ACK,然后server端的socket就被成功的关闭了.

     

    从这里可以看到,如果由客户端主动关闭一链接,那么客户端是不会出现CLOSE_WAIT状态的.客户端主动关闭链接,那么Server端将会出现CLOSE_WAIT的状态.

    而我们的服务器上,是客户端socket出现了CLOSE_WAIT,由此可见这个是由于server主动关闭了server上的socket.

     

    那么当server主动发起一个socket.close(),这个时候又发生了一些什么事情呢.

     

    从图中我们可以看到,如果是server主动关闭链接,那么Client则有可能进入CLOSE_WAIT,如果Client不发送FIN,那么client就一直会处在CLOSE_WAIT状态(后面我们可以看到有参数可以调整这个时间).

     

    那么现在我们要搞清楚的是,在第二中场景中,为什么Client不发送FIN包给server.要搞清楚这个问题,我们首先要搞清楚server是怎么发FIN包给client,其实server就是调用了

    socket.close方法而已,也就是说如果要client发送FIN,那么client就必须调用socket.close,否则就client就一直会处在CLOSE_WAIT

     

     

     

     

     





  • 相关阅读:
    C++ VC实现对话框窗口任意分割
    C++ 关于滚动条的滚动问题
    C++ 自定义控件的移植(将在其它程序中设计的自定义控件,移植到现在的系统中)
    C++ 动态创建按钮及 按钮的消息响应
    C++ Custom Control控件 向父窗体发送对应的消息
    C++ MFC 改变控件大小和位置
    C++ 使用VS2010创建MFC ActiveX工程项目
    VC++ 自定义控件的建立及使用方法
    C++ CTreeview的checkbox使用方法
    C++ vc中怎么使用SendMessage自定义消息函数
  • 原文地址:https://www.cnblogs.com/dimmacro/p/4460848.html
Copyright © 2011-2022 走看看