Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Problème avec socket.getsockname()

+1 vote

J'ai du code lamda:

try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("", 53))
    host, port = sock.getsockname()
except socket.error:
    raise exception.ProxyBindError("Could not bind port {}:{}".format(host, port))
    sys.exit(1)

Alors que ce code devrait me retourner

Could not bind port 0.0.0.0:53

il me crache ceci:

Traceback (most recent call last):
  File "core.py", line 59, in <module>
    raise exception.ProxyBindError("Could not bind port {}:{}".format(host, port))
NameError: name 'host' is not defined

Si je définis mon code ceci:

try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("", 53))
except socket.error:
    raise exception.ProxyBindError("Could not bind port {}:{}".format(sock.getsockname()[0], sock.getsockname()[1]))
    sys.exit(1)

le résultat n'est pas plus concluant:

Traceback (most recent call last):
  File "core.py", line 58, in <module>
    raise exception.ProxyBindError("Could not bind port {}:{}".format(sock.getsockname()[0], sock.getsockname()[1]))
exception.ProxyBindError: 'Could not bind port 0.0.0.0:0'

Du coup deux questions:
- pourquoi le tuple unpacking ne fonctionne pas?
- dans le second exemple sock.getsockname()[1] me retourne 0 alors que cela devrait clairement retourner 53.

P.S: Il est 3h du mat' donc je suis certain que j'ai juste de la me*** dans les yeux.

demandé 6-Aou-2016 par c0da (2,744 points)

1 Réponse

+3 votes
 
Meilleure réponse

C'est ce qui arrive lorsqu'on tente d'encadrer un "gros" bout de code dans un bloc try. Dans le premier cas, ça foire parce que l'exception est déclenchée avant gethostbyname, du coup l'unpacking n'a simplement pas lieu., et vu que tu catche l'exception originale tu ne sais plus ce qui se passe.

Je vais supposer que tu as une erreur 13 (Permission denied) vu que tu bind un port < 1024 (du coup je suppose aussi que tu es sous Unix), mais ça pourrait être autre chose. Du coup le bind foire, et tu reste bien sur les valeurs par défaut de getsockname.

En python 3, tu aurais eu moins de problèmes, parce que les deux exceptions sont levées dans un tel cas. Dans tous les cas, je pense que tu devrais faire comme ceci :

host, port = '0.0.0.0', 53
try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((host, port))
except socket.error as err:
    raise exception.ProxyBindError("Could not bind {}:{}, reason is '{}'".format(host, port, err.strerror))
    sys.exit(1)

En général, getsockname est surtout utilisé coté client, mais pas très utile dans ton cas.

Edit: vu le nom de ton exception, j'aurais même mis socket.socket en dehors du try.

répondu 7-Aou-2016 par yoch (2,062 points)
sélectionné 7-Aou-2016 par c0da
...