2

ソケットをリッスンするアプリケーションがあります。このアプリケーションは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

これを適切にキャッチする方法はありますか?

4

3 に答える 3

3

CLOSE_WAITstate は、ソケットがアプリケーションによって閉じられることが期待されることを意味します。

投稿したコードでは、ソケットは例外でのみ閉じられます。を受け取ったら必ずソケットを閉じてください。EOFつまり、ソケットをnot request削除する前に確認してください。

于 2012-06-28T08:25:08.723 に答える
1

リモート側によって接続が正常に閉じられると、標準のBSDrecv呼び出しはゼロを返します。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
于 2012-06-28T22:35:21.263 に答える
1

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 はそれを解決してくれました。

于 2016-06-30T17:52:25.897 に答える