Вопрос

Недавно я видел фрагмент кода, который выглядел следующим образом (конечно, sock является объектом сокета):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

Какова именно цель вызова завершения работы сокета и его последующего закрытия?Если это имеет значение, этот сокет используется для неблокирующего ввода-вывода.

Это было полезно?

Решение

Вот один объяснение:

Как только розетка больше не требуется, вызывающая программа может отказаться от гнезда, применив близкую подпрограмму к дескриптору сокета.Если надежный сокет доставки имеет данные, связанные с ним, когда происходит закрытие, система продолжает пытаться перенести данные.Однако, если данные все еще недоагированы, система отбрасывает данные.Если прикладная программа не имеет никакого использования для каких -либо ожидающих данных, она может использовать подпрограмму выключения в сокете до его закрытия.

Другие советы

Вызов close и shutdown имеют два разных эффекта на базовый сокет.

Первое, на что следует обратить внимание, это то, что сокет является ресурсом базовой ОС и несколько процессов могут иметь дескриптор одного и того же базового сокета.

Когда ты звонишь close он уменьшает количество дескрипторов на единицу, и если количество дескрипторов достигло нуля, сокет и связанное с ним соединение проходят обычную процедуру закрытия (фактически отправляя FIN/EOF одноранговому узлу), и сокет освобождается.

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

С другой стороны, вызов shutdown для чтения и записи закрывает базовое соединение и отправляет FIN/EOF одноранговому узлу независимо от того, сколько процессов имеют дескрипторы сокета.Однако это не освободите сокет, и вам все равно придется после этого вызывать close.

Объяснение отключения и закрытия: Грациозное завершение работы (msdn)

Выключение (в вашем случае) указывает на то, что на другом конце соединения нет дальнейших намерений читать или записывать в сокет.Затем close освобождает всю память, связанную с сокетом.

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

По моему мнению, названия «закрытие» и «закрытие» вводят в заблуждение, «закрыть» и «уничтожить» подчеркнут их различия.

это упоминается прямо в HOWTO по программированию сокетов (py2/py3)

Отключение

Строго говоря, вы должны использовать shutdown на розетке перед тобой close это.А shutdown это рекомендация для сокета на другом конце.В зависимости от аргумента, который вы передаете, это может означать «Больше отправлять не буду, но все равно послушаю", или "Я не слушаю, скатертью дорога!».Однако большинство библиотек сокетов настолько привыкли к тому, что программисты пренебрегают этим элементом этикета, который обычно close такой же как shutdown(); close().Поэтому в большинстве ситуаций явное завершение работы не требуется.

...

Разве этот код выше неправильный?

Вызов закрытия непосредственно после вызова завершения работы в любом случае может заставить ядро ​​отбросить все исходящие буферы.

В соответствии сhttp://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliableмежду выключением и закрытием нужно подождать, пока чтение не вернет 0.

есть несколько разновидностей отключения: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx.*nix аналогичен.

Shutdown(1) заставляет сокет no отправлять больше данных.

Это полезно в

1- Промывка буфера

2- Странное обнаружение ошибок

3- Надежная охрана

Позвольте мне объяснить больше, когда вы отправляете данные из A в B, он не гарантированно отправит B, это гарантированно будет отправлено в буфер ОС, который, в свою очередь, отправляет его в буфер B OS

Таким образом, позвонив по выходу (1) на A, вы промываете буфер A, и ошибка выдвигается, если буфер не пуст, т.е.данные еще не отправлены партнеру

Вы можете сделать это, так что вы можете сделать это после того, как вы полностью отправили все свои данные, и вы хотите быть уверенным, что это по крайней мере в буфере ОС.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top