2016-04-18 3 views
2

У меня есть небольшой сервер, работающий на моей малине Pi, который слушает в определенном порту. Однако всякий раз, когда возникает исключение во время соединения и соединение прекращается, кажется, что назначение порта не является «несвязанным».Программирование сокета на языке Python: «Адрес уже используется» после исключения

Это пример кода:

import socket 

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 
    s.bind(('', 5005)) 
    s.listen(1) 
    with s.accept()[0] as c: 
     raise Exception() # Act as if anything goes wrong 

Когда я запускаю его в первый раз, и сделать telnet localhost 5005 на другом терминале, подключение выполняется и сервер вызывает исключение, как и ожидалось. Однако, когда я пытаюсь запустить его во второй раз, я получаю эту ошибку:

Traceback (most recent call last): 
    File "testsocketexception.py", line 4, in <module> 
    s.bind(('', 5005)) 
OSError: [Errno 98] Address already in use 

Как я могу убедиться, что сокет несвязанный, даже если возникает исключение на сервере? (Кстати, похоже, что это не происходит в Windows.)

ответ

4

Установите опцию сокета SO_REUSEADDR, прежде чем связывать сокет.

the SO_REUSEADDR flag tells the kernel to reuse a local socket in TIME_WAIT state, without waiting for its natural timeout to expire.

from socket documentation


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    s.bind(('', 5005)) 
    ... 

Примечание: вы получите сообщение об ошибке, даже если применить это, если есть TIME_WAIT гнездо осталось от предыдущего запуска (без опции SO_REUSEADDR).

+0

Да, сейчас он работает, спасибо! – elzell

Смежные вопросы