it-swarm.com.de

Python-Server "Normalerweise ist nur eine Verwendung jeder Socket-Adresse zulässig."

Ich versuche, einen sehr einfachen Server in Python zu erstellen, der einen Port abhört, eine TCP -Verbindung erstellt, wenn ein Client versucht, eine Verbindung herzustellen, Daten empfängt, etwas zurückschickt und dann erneut abhört (und wiederholt den Vorgang unbegrenzt ). Das habe ich bisher:

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

Manchmal scheint das perfekt zu funktionieren (wenn ich meinen Browser auf "localhost: 4444" verweise, gibt der Server die HTTP-GET-Anforderung aus und die Webseite gibt den Text "Hallo Welt" aus). Ich erhalte jedoch die folgende Fehlermeldung sporadisch, wenn ich versuche, den Server nach dem Schließen in den letzten Minuten zu starten:

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

Ich programmiere in Python mit Windows 7. Irgendwelche Ideen, wie man das beheben kann?

17
scaevity

Aktivieren Sie die Option SO_REUSEADDR socket, bevor Sie bind () aufrufen. Dadurch kann die Adresse/der Port sofort wiederverwendet werden, anstatt für einige Minuten im TIME_WAIT-Status zu bleiben und auf verspätete Pakete zu warten.

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

Unter Windows können Sie folgende Schritte ausführen:

1. Prüfen Sie, welcher Prozess den Port verwendet.

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

sie werden so etwas bekommen:

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

2. Beenden Sie diesen Vorgang

tskill 19088

Viel Glück.

12
Rosin

In dem Artikel von @JohnKugelman wird angegeben, dass Sie den Socket auch nach dem Aktivieren von SO_REUSEADDR nicht verwenden können, um eine Verbindung zu demselben Remote-End wie zuvor herzustellen:

Mit SO_REUSADDR können Sie einen Port verwenden, der in TIME_WAIT stecken bleibt, jedoch Sie können diesen Port immer noch nicht verwenden, um eine Verbindung zum letzten .__ herzustellen. Platziere es mit verbunden.

Ich sehe, dass Sie gerade testen/herumspielen. Um diesen Fehler zu vermeiden, müssen Sie jedoch unbedingt sicherstellen, dass Sie die Verbindung ordnungsgemäß beenden. Sie können sich auch mit den TCP-Timings des Betriebssystems messen: http://www.linuxquestions.org/questions/linux-networking-3/decrease-time_wait-558399/

Zu Testzwecken wäre es auch gut, wenn Sie einfach Ihren serverPort in einem Round-Robin-Modus ändern. Was denken Sie dazu?

3

Es ist wichtig (besonders unter Windows), die Steckdose zu schließen. Andernfalls müssen Sie warten, bis nach dem Schließen von Python eine Zeitüberschreitung auftritt. 

Würde:

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

        print msg

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

hilfe?

0
jcater

Möglicherweise haben Sie den Servercode nicht beendet und versucht, ihn erneut auf einem anderen Cmd auszuführen. Der Server kann nicht auf derselben Portnummer gehostet werden. Versuchen Sie, den zuvor gehosteten Server zu beenden.

0
Rohan Desia

Wenn Sie versuchen, den Server erneut auszuführen, ohne den letzten Moment des Servers zu stoppen, funktioniert er nicht. Wenn Sie den aktuellen Moment stoppen möchten, gehen Sie zu 

Shell -> Starten Sie Shell neu. 

Wenn Sie die Shell bereits geschlossen haben, ohne den Server zu stoppen, gehen Sie zu den Pythonprozessen task manager und end task in den Hintergrundprozessoren. Dadurch wird der letzte Moment Ihres Servers angehalten.

0

Ich habe meine Portnummer in eine andere geändert und es funktioniert.

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