python套接字保持CLOSE_WAIT

时间:2012-06-28 08:05:43

标签: python sockets

我有一个应用程序,可以监听套接字。这个应用程序由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

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

3 个答案:

答案 0 :(得分:3)

CLOSE_WAIT state表示应用程序应该关闭套接字。

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

答案 1 :(得分:1)

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

您的代码可以说:

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

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

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

答案 2 :(得分:1)

您使用的是gevent-websockets库吗?

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

btw在socket上调用close()是不够的。来自python docs:(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它为我们解决了它。