2013-12-09 11 views
5

この質問はPythonに限定されません。その一般的なソケットの質問。私は非ブロッキングソケットを持っていて、到達可能なマシンに接続したい - 反対側のポートは存在しません。とにかく選択(...)が成功するのはなぜですか?私はタイムアウトが予想された。 sock.send(...)が壊れたパイプで失敗します。 select(...)の後にソケットが実際に接続されているかどうかを調べるにはどうすればよいですか? ありがとうございます。ノンブロッキング接続

import socket, errno, os, time, select 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.setblocking(0) 
err = sock.connect_ex(('192.168.178.21', 12345)) 
ready_to_read, ready_to_write, in_error = select.select([], [sock], [], timeout=5) 
#ready_to_write is set even 192.168.178.21:12345 does not exist. 

sock.setblocking(1) 
sock.send('foo') #this fails 
sock.close() 

答えて

4

戻り値を確認してください。ここで私は似たような状況で何を得るのです:ソケット上の例外条件があったので

>>> import socket, errno, os, time, select 
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
>>> sock.setblocking(0) 
>>> err = sock.connect_ex(('10.0.0.1', 12345)) 
>>> import errno 
>>> print errno.errorcode[err] 
EINPROGRESS 
>>> print sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) 
61 
>>> print errno.errorcode[61] 
ECONNREFUSED 

select()コールはおそらく戻っている - つまり、その接続が拒否されました。私はこれを行う場合は

は、すぐにselect()リターン:

>>> ready_to_read, ready_to_write, in_error = select.select([], [sock], []) 

そして興味深いことには、戻り値は(複数のソケットを持っていた場合、それはおそらく異なるだろう)あなたが渡されたかを正確に一致させます: select()

>>> print in_error 
[] 
>>> print ready_to_read 
[] 
>>> print ready_to_write 
[<socket._socketobject object at 0x10ccd0980>] 

デザイナーはあなたがループ内でselect()を実行するように期待して、あなたが書き込みをしようとすると、ソケットがエラーを返した場合、書き込みが失敗したときに、リストから削除されています。

だから、私の頭の上から、オプションのカップルを持っている:

  • あなたはソケットを読み、失敗しようとするまで、適切な行動を取る、待ってください。
  • 上記のようにgetsockopt()を使用して、ソケットで問題がないかどうかを確認したり、エラー状態であることを確認してから何かを試みてください。
+0

sock.getsockopt(socket.SOL_SOCKET、socket.SO_ERROR)は私のためのトリックでした。 – HelloWorld

+1

'getsockopt()'が返されてからソケットを読み書きしようとする間に、ソケットがシャットダウンする可能性があることに注意してください。 send/recvのエラーをうまく処理しようとする必要があります。 – mpontillo

関連する問題