【问题标题】:python socket stays CLOSE_WAITpython套接字保持CLOSE_WAIT
【发布时间】:2012-06-28 08:05:42
【问题描述】:

我有一个监听套接字的应用程序。此应用程序由 nagios 监控。问题是,nagios 打开套接字并直接关闭它们。我的应用程序套接字停留在 CLOSE_WAIT 中。我不明白为什么会这样。它应该会遇到错误并终止套接字。

           while request=="":
                    try:
                            request = self.client.recv ( 1024 ).rstrip()
                    except socket.timeout, msg:
                                    log.error( "no request")
                                    self.client.close()
                                    return
                    except socket.error, msg:
                                    print msg
                                    self.client.close()
                                    return
                    except msg:
                                    log.error(msg)
                                    self.client.close()
                                    return

任何想法如何正确捕捉到这个?

【问题讨论】:

    标签: python sockets


    【解决方案1】:

    CLOSE_WAIT 状态意味着套接字应该被应用程序关闭。

    在您发布的代码中,套接字仅在异常时关闭。确保在收到EOF 时关闭套接字,即在剥离之前检查not request

    【讨论】:

    • 如果对方关闭了流,就没有 EOF 等。我什么也没有收到!所以我不能关闭 eof...
    • @user1010775 如果对方关闭了流,那肯定是 EOS。
    【解决方案2】:

    当远程端正常关闭连接时,标准 BSD recv 调用返回零。在 Python 中,返回的值被转换为空字符串。在这两种情况下,它都不会被视为错误,因此您不应期待任何异常。

    你的代码可以说:

    request = self.client.recv(1024).rstrip()
    if not request:
      print "Connection closed"
      self.client.close()
    

    您还可以在 try-except 块之后关闭 finally 块中的连接以避免代码重复。如果您希望服务器在发送数据后关闭连接,您可以表示如下:

    request = ""
    r = True
    while r:
      r = self.client.recv(1024)
      request += r
    

    【讨论】:

      【解决方案3】:

      您在使用gevent-websockets 库吗?

      我们也遇到了这个问题,在self.stream = None 之前做了一个本地补丁,为我们解决了这个问题。

      顺便说一句,在套接字上调用 close() 是不够的。来自 python 文档:(https://docs.python.org/2/library/socket.html)

      注意 close() 释放与连接关联的资源,但不一定立即关闭连接。如果要及时关闭连接,请在close()之前调用shutdown()。

      $ diff /usr/lib/python2.7/dist-packages/geventwebsocket/websocket.py.orig /usr/lib/python2.7/dist-packages/geventwebsocket/websocket.py
      3c3
      < from socket import error
      ---
      > from socket import error, SHUT_RDWR
      372a373,379
      > 
      >             try:
      >                 # if we don't close, leaks open files in a CLOSE_WAIT state
      >                 self.stream.handler.socket.shutdown(SHUT_RDWR)
      >                 self.stream.handler.socket.close()
      >             except:
      >                 pass
      

      注意该方法中有一条注释:

      关闭websocket和连接,发送指定的代码和消息。底层的套接字对象没有关闭,这是发起者的责任。

      所以这是否“正确”是有争议的,但 EOD 它为我们解决了这个问题。

      【讨论】:

        猜你喜欢
        • 2014-10-02
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        • 1970-01-01
        • 2013-03-17
        • 2013-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多