Закрытие TCP-сервера зависло на TIME_WAIT, невозможно снова открыть сервер на том же порту

Я использую LwIP 1.4.1, закрытие моего TCP-сервера зависло в состоянии TIME_WAIT, поэтому я не могу снова открыть сервер на том же порту. Я пробовал SO_REUSE (#define SO_REUSEADDR 1), но это тоже не работает, у кого есть идеи?

Во время ожидания я проверил, что примерно через 30 секунд он истекает, я не хочу ждать так долго.


person Ishmeet    schedule 15.10.2013    source источник
comment
Я предполагаю, что проблема в рукопожатии. Вы пытаетесь закрыть сокет, поэтому сервер проверяет с помощью TIME_WAIT, что в канале больше нет данных, но другая сторона постоянно отправляет данные. Поправьте меня, если я ошибаюсь?   -  person Dayal rai    schedule 15.10.2013
comment
Что вы имеете в виду под #define SO_REUSEADDR 1? Это неправильный способ установки SO_REUSEADDR.   -  person DoxyLover    schedule 15.10.2013
comment
@Dayalrai да, проблема в рукопожатии, я вижу правильное рукопожатие на сниффере, то есть сервер отправляет FIN, получает ACK, получает FIN, отправляет ACK. Но на модуле его состояние подключения не меняется, оно застревает на TIME_WAIT. С другой стороны, удаленный компьютер перестает отправлять данные, его соединение закрывается, и он не может снова подключиться.   -  person Ishmeet    schedule 15.10.2013


Ответы (2)


Вы должны установить опцию сокета SO_REUSEADDR перед вызовом bind():

Linux разрешает повторное использование порта только с параметром SO_REUSEADDR, если этот параметр был установлен как в предыдущей программе, которая выполняла привязку (2) к порту, так и в программе, которая хочет повторно использовать порт. Это отличается от некоторых реализаций (например, FreeBSD), где только более поздняя программа должна устанавливать параметр SO_REUSEADDR. Обычно эта разница незаметна, поскольку, например, серверная программа всегда устанавливает этот параметр.

Тот факт, что вам все еще нужно ждать, указывает на то, что опция не была установлена.

person Maxim Egorushkin    schedule 15.10.2013
comment
Я не работаю в Linux, у меня есть идеи, как использовать его в Raw TCP в LwIP версии 1.4.1. Я смог найти только этот макрос #define SO_REUSE 1, облазил форумы, не нашел. - person Ishmeet; 15.10.2013
comment
Макрос @Ishmeet SO_REUSE должен быть установлен при компиляции библиотеки LwIP. Была ли ваша библиотека LwIP скомпилирована с включенным макросом? - person Maxim Egorushkin; 16.10.2013
comment
ДА, это внутри opt.h, и я перекомпилировал все это, в качестве доказательства у меня есть отладочное сообщение внутри макроса #if SO_REUSE, и оно печатается. - person Ishmeet; 17.10.2013
comment
@Ishmeet Хорошо, тогда вам может повезти, спросив экспертов LwIP в их списках рассылки: savannah.nongnu .org/mail/?group=lwip - person Maxim Egorushkin; 17.10.2013

установить параметр сокета SO_REUSEADDR. Еще один момент использования SO_REUSEADDR может через ошибку "адрес уже используется". SO_REUSADDR позволяет использовать порт, который застрял в TIME_WAIT, но мы по-прежнему не можем использовать этот порт для установления соединения с последним портом, к которому он подключался. если сервер находится на 3000, и подключитесь к клиентскому порту 4000, а затем закройте локально, оставив этот порт в TIME_WAIT. мы можем сразу повторно использовать серверный порт 4000 для подключения к чему угодно, кроме клиентского порта 4000

person user3148376    schedule 07.11.2014