web-dev-qa-db-fra.com

Python exception de connexion de socket

J'ai une connexion socket en cours et je veux améliorer la gestion des exceptions et je suis bloqué. Chaque fois que j'utilise la fonction socket.connect (adresse_serveur) avec un argument invalide, le programme s'arrête, mais ne semble pas lever d'exception. Voici mon code

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()

La classe semble peut-être un peu bizarre, mais elle est utilisée pour recevoir des coordonnées d'un autre ordinateur exécutant ARToolKit. Quoi qu'il en soit, le problème est lié à la fonction 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)

Si j'appelle cette fonction avec une adresse IP aléatoire et un numéro de port, tout le programme s'arrête juste à la ligne:

self.sock.connect(server_address)

La documentation que j'ai lue indique qu'en cas d'erreur, elle lèvera une exception socket.error. J'ai aussi essayé avec juste:

except Exception, msg:

Cela, si je ne me trompe pas, entraînera des exceptions, et cela ne donnera toujours aucun résultat. Je serais très reconnaissant pour un coup de main. En outre, est-il correct de quitter les programmes à l'aide de sys.exit lorsqu'une exception indésirable se produit?

Je vous remercie

11
erling

Si vous avez choisi une adresse IP et un port aléatoires mais valides, socket.connect() tentera d'établir une connexion avec ce point de terminaison. Par défaut, si aucun délai d'expiration explicite n'est défini pour le socket, il se bloquera lors de cette opération et finira par expirer, levant l'exception socket.error: [Errno 110] Connection timed out.

Le délai d'expiration par défaut sur ma machine est de 120 secondes. Peut-être n'attendez-vous pas assez longtemps pour que socket.connect() revienne (ou timeout)?

Vous pouvez essayer de réduire le délai d'attente comme ceci:

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

Notez que si un délai d'attente est explicitement défini pour le socket, l'exception sera socket.timeout Qui est dérivée de socket.error Et sera donc interceptée par la clause except ci-dessus.

16
mhawke

Le problème avec votre dernière exception générale est le placement du côlon. Elle doit se trouver après l'exception entière, pas après l'instruction except. Ainsi, pour capturer toutes les exceptions, vous devez effectuer:

except Exception,msg:

Cependant, à partir de Python 2.6+, vous devez utiliser l'instruction as au lieu d'une virgule comme ceci:

except Exception as msg:

J'ai pu exécuter le code correctement (notez que vous devez ajouter un tuple à la méthode de connexion). Si vous souhaitez spécifiquement détecter uniquement les erreurs de socket, vous devez exclure le socket.error classe. Comme vous l'avez:

except socket.error as msg:

Si vous voulez vous assurer qu'un Tuple est entré, ajoutez simplement une autre boucle d'exception:

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