web-dev-qa-db-ja.com

Pythonソケット接続例外

ソケット接続が行われていますが、例外処理を改善したいと思います。無効な引数を指定してsocket.connect(server_address)関数を使用すると、プログラムは停止しますが、例外はスローされないようです。ここに私のコード

_import socket
import sys
import struct
class ARToolkit():

    def __init__(self):
        self.x = 0
        self.y = 0
        self.z = 0
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.logging = False


    def connect(self,server_address):
        try:
            self.sock.connect(server_address)
        except socket.error, msg:
            print "Couldnt connect with the socket-server: %s\n terminating program" % msg
            sys.exit(1)


    def initiate(self):
        self.sock.send("start_logging")

    def log(self):
        self.logging  = True  
        buf = self.sock.recv(6000)
        if len(buf)>0:
            nbuf = buf[len(buf)-12:len(buf)]
            self.x, self.y, self.z = struct.unpack("<iii", nbuf)





    def stop_logging(self):
        print "Stopping logging"
        self.logging = False
        self.sock.close()
_

クラスは少し奇妙に見えるかもしれませんが、ARToolKitを実行している別のコンピューターから座標を受け取るために使用されます。とにかく、問題は関数connect()にあります:

_def connect(self,server_address):
        try:
            self.sock.connect(server_address)
        except socket.error, msg:
            print "Couldnt connect with the socket-server: %s\n terminating program" % msg
            sys.exit(1)
_

ランダムなIPアドレスとポート番号でこの関数を呼び出すと、プログラム全体が次の行で停止します。

_self.sock.connect(server_address)
_

私が読んだドキュメントには、エラーが発生するとsocket.error-exceptionがスローされると書かれています。私も試しました:

_except Exception, msg:
_

これは、私が間違っていなければ、例外をキャッチしますが、それでも結果は得られません。私は救いの手にとても感謝しています。また、不要な例外が発生したときにsys.exitを使用してプログラムを終了しても大丈夫ですか?

ありがとうございました

11
erling

ランダムだが有効なIPアドレスとポートを選択した場合、socket.connect()はそのエンドポイントへの接続を試みます。デフォルトでは、ソケットに明示的なタイムアウトが設定されていない場合、ブロック中にブロックされ、最終的にタイムアウトになり、例外_socket.error: [Errno 110] Connection timed out_が発生します。

私のマシンのデフォルトのタイムアウトは120秒です。おそらく、socket.connect()が戻る(またはタイムアウトする)のに十分な時間待機していないのでしょうか。

次のようにタイムアウトを短くしてみてください:

_import socket

s = socket.socket()
s.settimeout(5)   # 5 seconds
try:
    s.connect(('123.123.123.123', 12345))         # "random" IP address and port
except socket.error, exc:
    print "Caught exception socket.error : %s" % exc
_

ソケットにタイムアウトが明示的に設定されている場合、例外は_socket.timeout_から派生した_socket.error_になり、したがって上記のexcept節によってキャッチされます。

16
mhawke

最後の一般的な例外の問題は、コロンの配置です。 exceptステートメントの後ではなく、例外全体の後でなければなりません。したがって、すべての例外をキャプチャするには、以下を行う必要があります。

except Exception,msg:

ただし、Python 2.6+からは、次のようなコンマの代わりにasステートメントを使用する必要があります。

except Exception as msg:

コードを正常に実行できました(connectメソッドにTupleをスローする必要があることに注意してください)。ソケットエラーのみを具体的にキャッチする場合は、socket.errorクラス。あなたが持っているように:

except socket.error as msg:

タプルが入力されたことを確認したい場合は、別の例外ループを追加します。

except socket.error as msg:
    print "Socket Error: %s" % msg
except TypeError as msg:
    print "Type Error: %s" % msg
5
user3960432