web-dev-qa-db-fra.com

Serveur Python "Une seule utilisation de chaque adresse de socket est normalement autorisée"

J'essaie de créer un serveur très basique en python qui écoute sur un port, crée une connexion TCP lorsqu'un client essaie de se connecter, reçoit des données, renvoie quelque chose, puis écoute à nouveau (et répète le processus indéfiniment ). C'est ce que j'ai jusqu'ici:

from socket import *

serverName = "localhost"
serverPort = 4444
BUFFER_SIZE = 1024

s = socket(AF_INET, SOCK_STREAM)
s.bind((serverName, serverPort))
s.listen(1)

print "Server is ready to receive data..."

while 1:
        newConnection, client = s.accept()
        msg = newConnection.recv(BUFFER_SIZE)

        print msg

        newConnection.send("hello world")
        newConnection.close()

Parfois, cela semble fonctionner parfaitement (si je pointe mon navigateur sur "localhost: 4444", le serveur imprime la requête HTTP GET et la page Web imprime le texte "hello world"). Mais le message d'erreur suivant s'affiche sporadiquement lorsque j'essaie de démarrer le serveur après l'avoir fermé au cours des dernières minutes:

Traceback (most recent call last):
  File "path\server.py", line 8, in <module>
    s.bind((serverName, serverPort))
  File "C:\Python27\lib\socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

Je programme en python sous Windows 7. Vous avez des idées pour résoudre ce problème?

17
scaevity

Activez l'option SO_REUSEADDR socket avant d'appeler bind (). Cela permet à l'adresse/au port d'être réutilisés immédiatement au lieu de rester bloqués dans l'état TIME_WAIT pendant plusieurs minutes, en attendant l'arrivée des derniers paquets.

s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
18
John Kugelman

Sous Windows, vous pouvez essayer ces étapes:

1. Vérifiez quel processus utilise le port.

# 4444 is your port number
netstat -ano|findstr 4444

vous obtiendrez quelque chose comme ceci:

# 19088 is the PID of the process
TCP    0.0.0.0:4444           *:*                                    19088

2. tuer ce processus

tskill 19088

Bonne chance.

12
Rosin

Dans l'article posté par @JohnKugelman, il est indiqué que même après avoir activé SO_REUSEADDR, vous ne pouvez pas utiliser le socket pour vous connecter à la même extrémité distante qu'avant:

SO_REUSADDR vous permet d'utiliser un port bloqué dans TIME_WAIT, mais vous ne pouvez toujours pas utiliser ce port pour établir une connexion avec le dernier fichier placez-le connecté à.

Je vois que vous testez/jouez. Cependant, pour éviter cette erreur, vous devez vraiment vous assurer que vous mettez fin à la connexion correctement. Vous pouvez également jouer avec les timings TCP du système d’exploitation: http://www.linuxquestions.org/questions/linux-networking-3/decrease-time_wait-558399/

À des fins de test, ce serait également bien si vous changiez simplement votre serverPort à tour de rôle, que pensez-vous?

3
Jan-Philip Gehrcke

Il est important (sous Windows en particulier) de fermer le socket. Sinon, vous devez attendre l'expiration du délai après la fermeture de Python. 

Aurait:

try:
    while 1:
        newConnection, client = s.accept()
        msg = newConnection.recv(BUFFER_SIZE)

        print msg

        newConnection.send("hello world")
        newConnection.close()
finally:
    s.close()

aidez-moi?

0
jcater

Si vous essayez de réexécuter le serveur sans arrêter le dernier instant du serveur, cela ne fonctionnera pas. Si vous voulez arrêter l'instant présent, allez à 

Shell -> redémarrer Shell.  

Si vous avez déjà fermé le shell sans Arrêter le serveur, accédez au processus gestionnaire de tâches et fin tâche python dans les processeurs en arrière-plan. Cela arrêtera le dernier instant de votre serveur.

0
Sudeepa Nadeeshan

J'ai changé mon numéro de port en un autre et cela fonctionne.

if __== '__main__':
    socketio.run(app, debug = True, use_reloader = False, port=1111)
0
Jelly