我有一个应用程序,可以监听套接字。这个应用程序由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
任何想法如何正确捕捉这个?
答案 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它为我们解决了它。