Python server "Разрешено только одно использование каждого адреса сокета"

Я пытаюсь создать очень простой сервер на python, который прослушивает порт, создает TCP-соединение, когда клиент пытается подключиться, получает данные, отправляет что-то обратно, а затем снова прослушивает (и повторяет процесс на неопределенный срок), Это то, что у меня есть до сих пор:

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

Иногда это работает отлично (если я укажу свой браузер на "localhost: 4444", сервер распечатает запрос HTTP GET, а веб-страница распечатает текст "hello world" ). Но я получаю следующее сообщение об ошибке случайным образом, когда я пытаюсь запустить сервер после его закрытия за последние несколько минут:

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

Я программирую на python, используя Windows 7. Любые идеи о том, как исправить это?

Ответ 1

Включите опцию SO_REUSEADDR перед вызовом bind(). Это позволяет повторно использовать адрес/порт, а не задерживаться в состоянии TIME_WAIT в течение нескольких минут, ожидая появления последних пакетов.

s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

Ответ 2

В Windows вы можете попробовать эти шаги:

1. проверьте, какой процесс использует порт.

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

вы получите что-то вроде этого:

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

2. убить этот процесс

С:

tskill 19088

Или же:

taskkill /F /PID 19088

Удачи.

Ответ 3

В в статье, опубликованной @JohnKugelman, говорится, что даже после включения SO_REUSEADDR вы не можете использовать сокет для подключения к тому же удаленному конец по-прежнему:

SO_REUSADDR позволяет использовать порт, который застрял в TIME_WAIT, но вы все еще не можете использовать этот порт для установления соединения с последним установите его на.

Я вижу, что вы просто тестируете/играете. Однако, чтобы избежать этой ошибки, вам действительно нужно убедиться, что вы прекратите соединение правильно. Вы также можете использовать тайм-ауты tcp операционной системы: http://www.linuxquestions.org/questions/linux-networking-3/decrease-time_wait-558399/

В целях тестирования было бы также хорошо, если бы вы просто изменили свой serverPort круговым способом, как вы думаете?

Ответ 4

Это важно (для Windows специально) закрыть сокет. В противном случае вам придется подождать до таймаута после закрытия Python.

Будет:

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

        print msg

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

помощь?

Ответ 5

Если вы пытаетесь перезапустить сервер, не останавливая последний момент сервера, он не будет работать. Если вы хотите остановить текущий момент, перейдите в

shell → перезапустить оболочку.

Если вы уже закрыли оболочку без остановив сервер, перейдите в процесс диспетчер задач и завершение задачи python в фоновых обработчиках. Это остановит последний момент вашего сервера.

Ответ 6

Я изменил свой номер порта на другой, и он работает.

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

Ответ 7

Это может быть потому, что вы не завершили серверный код и не попытались запустить его снова на другом cmd. Сервер не может быть размещен на том же номере порта, попробуйте убить предыдущий сервер.