2010-06-07 3 views
4

У меня есть служба, которая связывается через tcpListener. Проблема заключается в том, когда пользователь перезапускает службу - генерируется исключение «Адрес уже используется», и служба не может быть запущена на пару минут или около того.Как я могу принудительно закрыть TcpListener

Есть ли способ сообщить системе о прекращении старого соединения, чтобы я мог открыть новый? (Я не могу просто использовать случайные порты, потому что нет возможности для службы уведомлять клиентов о том, что такое порт, поэтому мы должны зависеть от предопределенного порта)

ответ

3

Установите опцию сокета SO_REUSEADDR перед привязкой к порту прослушивания , Похоже, что соответствующий код .NET выглядит примерно так:

SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); 
+0

Спасибо. прекрасно работает – Nissim

1

Существует причина, по которой сокеты не используются в течение некоторого времени после их закрытия. Сокет состоит из 4 кортежей, источника и порта Dest, Source и Dest IP.

Предположим, вы закрыли сокет принудительно, а клиент был занят отправкой данных на сервер. Вы ожидаете 5 секунд и повторно открываете сервер с тем же портом, и тот же клиент отправляет данные в один и тот же 4 кортежа, сервер получит пакеты с неправильными номерами последовательности tcp, и соединения будут сброшены.

Вы стреляете себе в ногу :)

Поэтому соединения имеют статус TIME_WAIT в течение 2-4 минут (в зависимости от дистрибутива), пока они не могут быть использованы снова. Чтобы быть ясным, я говорю о SOCKET, а не только о прослушиваемом порту tcp.

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