J'essaie de comprendre comment utiliser le try et sauf pour gérer un délai d'attente de socket.
from socket import *
def main():
client_socket = socket(AF_INET,SOCK_DGRAM)
client_socket.settimeout(1)
server_Host = 'localhost'
server_port = 1234
while(True):
client_socket.sendto('Message',(server_Host,server_port))
try:
reply, server_address_info = client_socket.recvfrom(1024)
print reply
except socket.Timeouterror:
#more code
La façon dont j'ai ajouté le module de socket consistait à tout importer, mais comment puis-je gérer les exceptions dans la documentation? Il est dit que vous pouvez utiliser socket.timeouterror, mais cela ne fonctionne pas pour moi. De plus, comment écrirais-je le bloc d'exception try si je connaissais import socket
? Quelqu'un peut-il également expliquer la différence entre les importations.
from foo import *
ajoute tous les noms sans traits de soulignement (ou uniquement les noms définis dans l'attribut modules __all__
) de foo
dans votre module actuel.
Dans le code ci-dessus avec from socket import *
, vous voulez juste attraper timeout
car vous avez tiré timeout
dans votre espace de noms actuel.
from socket import *
extrait les définitions de tout ce qui se trouve à l'intérieur de socket
mais n'ajoute pas socket
lui-même.
try:
# socketstuff
except timeout:
print 'caught a timeout'
Plusieurs personnes considèrent que import *
est problématique et tentent de l'éviter. Cela s'explique par le fait que les noms de variable courants dans 2 modules ou plus ainsi importés s'embrouillent.
Par exemple, considérons les trois fichiers python suivants:
# a.py
def foo():
print "this is a's foo function"
# b.py
def foo():
print "this is b's foo function"
# yourcode.py
from a import *
from b import *
foo()
Si vous exécutez yourcode.py
, vous verrez juste le résultat "c'est la fonction foo de b".
Pour cette raison, je suggérerais soit d'importer le module et de l'utiliser, soit d'importer des noms spécifiques à partir du module:
Par exemple, votre code ressemblerait à ceci avec des importations explicites:
import socket
from socket import AF_INET, SOCK_DGRAM
def main():
client_socket = socket.socket(AF_INET, SOCK_DGRAM)
client_socket.settimeout(1)
server_Host = 'localhost'
server_port = 1234
while(True):
client_socket.sendto('Message', (server_Host, server_port))
try:
reply, server_address_info = client_socket.recvfrom(1024)
print reply
except socket.timeout:
#more code
Juste un peu plus de dactylographie mais tout est explicite et le lecteur sait très bien d'où vient tout.
J'ai eu assez de succès, juste catchig socket.timeout
et socket.error
; bien que socket.error puisse être soulevé pour de nombreuses raisons. Faites attention.
import socket
import logging
hostname='google.com'
port=443
try:
sock = socket.create_connection((hostname, port), timeout=3)
except socket.timeout as err:
logging.error(err)
except socket.error as err:
logging.error(err)
Lorsque vous le faites, from socket import *
python charge un module socket
dans l'espace de noms actuel. Ainsi, vous pouvez utiliser les membres du module comme s'ils étaient définis dans votre module python actuel.
Lorsque vous faites import socket
, un module est chargé dans un espace de noms séparé. Lorsque vous accédez à ses membres, vous devez les préfixer avec un nom de module. Par exemple, si vous souhaitez faire référence à une classe socket
, vous devrez écrire client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
.
En ce qui concerne le problème de l'expiration du délai, il suffit de changer except socket.Timeouterror:
en except timeout:
, puisque la classe timeout
est définie dans le module socket
et que vous avez importé tous ses membres dans votre espace de noms.
Voici une solution que j'utilise dans l'un de mes projets.
network_utils.telnet
import socket
from timeit import default_timer as timer
def telnet(hostname, port=23, timeout=1):
start = timer()
connection = socket.socket()
connection.settimeout(timeout)
try:
connection.connect((hostname, port))
end = timer()
delta = end - start
except (socket.timeout, socket.gaierror) as error:
logger.debug('telnet error: ', error)
delta = None
finally:
connection.close()
return {
hostname: delta
}
def test_telnet_is_null_when_Host_unreachable(self):
hostname = 'unreachable'
response = network_utils.telnet(hostname)
self.assertDictEqual(response, {'unreachable': None})
def test_telnet_give_time_when_reachable(self):
hostname = '127.0.0.1'
response = network_utils.telnet(hostname, port=22)
self.assertGreater(response[hostname], 0)