2010-07-12 4 views
39

От человека странице:Что такое SO_REUSEADDR (опция setsockopt) - Linux?

SO_REUSEADDR Указывает, что правила , используемые в тестирующих адресов поставляется для связывания() должен позволять повторное использование локальных адресов , если это поддерживается протоколом . Этот параметр принимает значение int . Это логическая опция

Когда следует использовать ее? Почему «повторное использование локальных адресов» дает?

+0

Я не понимаю, почему этот вопрос отмечен vC++ ... –

+0

Ошибка. Я имел ввиду C++. Спасибо. –

+5

Это все еще не имеет ничего общего с C++ :) –

ответ

18

SO_REUSEADDR позволяет серверу привязки к адресу, который находится в состоянии с
TIME_WAIT.

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

От unixguide.net

+0

Большое спасибо, я тоже нашел это, но все равно не понял ... –

+3

Предположим, вы открыли TCP-соединение. После передачи данных вы закрываете сокет. Но на самом деле он будет установлен в состоянии TIME_WAIT (TIME_WAIT ==), возможно, что некоторые данные еще не были доставлены или что-то еще, поэтому мы ждем как предостерегающая реализация TCP :) »). Вы просто не можете открыть другое соединение с тем же IP-портом, за исключением использования REUSEADDR. –

+0

Пенни упали. Большое спасибо! –

82

первичный дизайн цели TCP является, чтобы позволить надежную передачу данных в условиях потери пакетов, пакетов переназначения и — ключа, здесь дублирования — пакетов.

Довольно очевидно, что сетевой стек TCP/IP имеет дело со всем этим, пока соединение завершено, но есть крайний случай, который происходит сразу после закрытия соединения. Что произойдет, если пакет, отправленный в конце разговора, дублируется и задерживается, так что пакеты the 4-way shutdown добираются до получателя до отложенного пакета? Стек аккуратно закрывает соединение. Затем появляется всплывающий дублированный пакет. Что должен делать стек?

Что еще более важно, что делать, если программа, которая принадлежала этому соединению, сразу же умирает, а затем запускает один и тот же IP-адрес и номер порта TCP?

Есть несколько вариантов:

  1. повторное Disallow этого комбо IP/порт, по крайней мере, в 2 раза максимальное время пакет может находиться в полете. В TCP это обычно называют задержкой 2 × MSL. Иногда вы также видите 2 × RTT, что примерно эквивалентно.

    Это поведение по умолчанию для всех распространенных стеков TCP/IP. 2 × MSL обычно составляет от 30 до 120 секунд. (Это период TIME_WAIT.) После этого времени стек предполагает, что все пакеты-изгои были опущены по маршруту из-за истекшего TTLs, поэтому он оставляет состояние TIME_WAIT, позволяя повторному использованию этой комбинации IP/port.

  2. Позволяет новой программе повторно привязываться к этой комбинации IP/port.В пакетах с BSD sockets интерфейсами — по существу все Unix и Unix-подобные системы, а также Windows через Winsock —, вы должны попросить об этом, установив опцию SO_REUSEADDR через setsockopt(), прежде чем позвонить по телефону bind().

SO_REUSEADDR чаще всего устанавливается в серверных программах.

Причина в том, что вы изменяете конфигурационный файл сервера и должны перезапустить этот сервер, чтобы перезагрузить его конфигурацию. Без SO_REUSEADDR вызов bind() в новом экземпляре новой программы перезапустится, если были открыты соединения с предыдущим экземпляром, когда вы его убили. Эти соединения будут удерживать порт TCP в состоянии TIME_WAIT в течение 30-120 секунд, поэтому вы попадете в случай 1 выше.

Безопасная вещь - это подождать TIME_WAIT, но на практике это не очень большой риск того, что это стоит того. Лучше сразу вернуть сервер обратно, чтобы не пропустить больше входящих соединений, чем необходимо.

+4

Отличный и очень полезный ответ. BTW: обратите внимание, что следующая цитата [man 7 ip] (http: //linux.die.net/man/7/ip): * Адрес локального сокета TCP, который был связан, недоступен в течение некоторого времени после закрытия, если не установлен флаг SO_REUSEADDR. ** Следует соблюдать осторожность при использовании этого флага, поскольку он делает TCP менее надежным. *** не очень полезно без приведенного выше объяснения. –

6

Когда вы создаете сокет, вы действительно не владеете им. ОС (стек TCP) создает его для вас и предоставляет вам дескриптор (файловый дескриптор) для доступа к нему. Когда ваш сокет закрыт, для ОС требуется время «полностью закрыть», пока оно проходит через несколько состояний. Как упоминалось в комментариях EJP, самая длинная задержка обычно происходит из состояния TIME_WAIT. Эта дополнительная задержка требуется для обработки крайних случаев в самом конце последовательности завершения и обеспечения того, чтобы последнее подтверждение завершения было либо пройдено, либо было сброшено с другой стороны из-за таймаута. Here you can find некоторые дополнительные соображения относительно этого состояния. Основные соображения указаны следующим образом:

Помните, что протокол TCP гарантирует, что все переданные данные будут доставлены, , если это вообще возможно. Когда вы закрываете сокет, сервер переходит в состояние TIME_WAIT, просто чтобы быть действительно уверенным, что все данные имеют . Когда сокет закрыт, обе стороны соглашаются, отправив сообщениям друг другу, что они не отправят больше данных. Это, показалось мне достаточно хорошим, и после того, как рукопожатие сделано, гнездо должно быть закрыто. Проблема в два раза. Во-первых, нет , чтобы быть уверенным, что последний ответ был успешно передан. Во-вторых, в сети могут находиться «блуждающие дубликаты», которые должны быть обработаны, если они доставляются до .

Если вы попытаетесь создать несколько сокетов с той же парой ip: port действительно быстро, вы получите ошибку «адрес уже используется», потому что более ранний сокет не будет полностью выпущен. Использование SO_REUSEADDR избавится от этой ошибки, поскольку оно переопределит проверки для любого предыдущего экземпляра.

+0

Я думаю, что эта фраза была самой важной, и никто ее не упоминал раньше: «Если вы попытаетесь создать несколько сокетов с той же самой парой ip: port действительно быстро, вы получите ошибку« адрес уже используется ». Стоит на голосование :) –

+1

IT не «уделяет время ОС, чтобы« заметить »его. Существует * определенное состояние TCP *, называемое TIME_WAIT, в котором спецификация протокола TCP * требует * операционной системы поддерживать порт до его окончательного освобождения. Это состояние отправляет закрытие связанного сокета. – EJP