Вызов close
и shutdown
имеют два разных эффекта на базовый сокет.
Первое, на что следует обратить внимание, это то, что сокет является ресурсом в базовой ОС и несколько процессов могут иметь дескриптор для одного и того же базового сокета.
Когда вы вызываете close
его, счетчик дескрипторов уменьшается на единицу, и если счетчик дескрипторов достиг нуля, то сокет и связанное с ним соединение проходят обычную процедуру закрытия (фактически отправляя FIN / EOF партнеру), и сокет освобождается.
Здесь следует обратить внимание на то, что если счетчик дескрипторов не достигает нуля, потому что другой процесс все еще имеет дескриптор для сокета, тогда соединение не закрывается и сокет не освобождается.
С другой стороны, вызов shutdown
для чтения и записи закрывает базовое соединение и отправляет FIN / EOF партнеру, независимо от того, сколько процессов имеет дескрипторы для сокета. Однако он не освобождает сокет, и вам все равно нужно вызвать close после этого.
shutdown()
делает :).shutdown()
и на следующей линии.close()
? Или должна быть задержка между ними?Объяснение выключения и закрытия: плавное выключение (msdn)
Завершение работы (в вашем случае) указывает на другой конец соединения, что больше нет намерения читать или писать в сокет. Затем close освобождает всю память, связанную с сокетом.
Отсутствие выключения может привести к тому, что сокет задержится в стеке ОС до тех пор, пока соединение не будет корректно закрыто.
ИМО названия «выключение» и «закрытие» вводят в заблуждение, «закрыть» и «уничтожить» подчеркнут их различия.
источник
он упоминается прямо в HOWTO по программированию сокетов ( py2 / py3 )
источник
close()
достаточно. Документацию Python следует исправить.Не ошибается ли приведенный выше код?
Вызов закрытия непосредственно после вызова выключения может заставить ядро в любом случае отбросить все исходящие буферы.
Согласно 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), заставляет сокет не отправлять больше данных
Это полезно в
1- Промывка буфера
2- Обнаружение странной ошибки
3- Надежная охрана
Позвольте мне объяснить больше, когда вы отправляете данные из A в B, они не гарантируются, что они будут отправлены в B, они гарантированно будут отправлены только в буфер A os, который, в свою очередь, отправляет их в буфер B os.
Таким образом, вызывая shutdown (1) для A, вы очищаете буфер A, и возникает ошибка, если буфер не пуст, то есть: данные еще не отправлены партнеру
Как бы то ни было, это необратимо, поэтому вы можете сделать это после того, как полностью отправите все свои данные, и вы хотите быть уверены, что они по крайней мере в буфере одноранговой ОС.
источник