Что такое код socket_shutdown

Close vs shutdown socket?

170 root [2010-11-12 02:38:00]

В C я понял, что если мы закроем сокет, это значит, что сокет будет уничтожен и может быть повторно использован позже.

Как насчет остановки? В описании говорится, что он закрывает половину дуплексного соединения с этим сокетом. Но будет ли этот сокет разрушен, как системный вызов close ?

c networking sockets

8 ответов

150 Решение Matthew Flaschen [2010-11-12 02:39:00]

Это объясняется в руководстве по сети Beej. shutdown — это гибкий способ блокировки связи в одном или обоих направлениях. Когда вторым параметром является SHUT_RDWR , он будет блокировать отправку и получение (например, close ). Тем не менее, close — это способ уничтожить сокет.

При shutdown вы все равно сможете получать ожидающие данные, которые уже отправили peer (спасибо Джои Адамсу за это замечание).

Ни один из существующих ответов не говорит людям, как shutdown и close работают на уровне протокола TCP, поэтому стоит добавить это.

Стандартное TCP-соединение прекращается с помощью 4-сторонней финализации:

  1. После того, как у участника больше нет данных для отправки, он отправляет пакет FIN другому
  2. Другая сторона возвращает ACK для FIN.
  3. Когда другая сторона также завершила передачу данных, она отправляет другой пакет FIN
  4. Первоначальный участник возвращает ACK и завершает передачу.

Тем не менее, существует еще один «возникающий» способ закрыть TCP-соединение:

  1. Участник отправляет RST-пакет и отказывается от соединения
  2. Другая сторона получает RST, а затем отказывается от соединения

В моем тесте с Wireshark, с настройками сокета по умолчанию, shutdown отправляет FIN-пакет на другой конец, но это все, что он делает. Пока другая сторона не отправит вам пакет FIN, вы все еще можете получать данные. Как только это произойдет, ваш Receive получит результат в размере 0. Поэтому, если вы первый, кто закрыл «отправить», вы должны закрыть сокет, как только вы закончите получать данные.

С другой стороны, если вы звоните close в то время как соединение остается активным (другая сторона по — прежнему активна, и вы можете иметь неотправленные данные в буфере системы, а), пакет RST будет отправлен в другую сторону. Это полезно для ошибок. Например, если вы считаете, что другая сторона предоставила неверные данные или отказалась предоставить данные (DOS-атака?), Вы можете сразу же закрыть сокет.

Мое мнение о правилах было бы:

  1. Рассмотрите возможность shutdown до close когда это возможно
  2. Если вы закончили получать (0 полученных данных размера) до того, как решили завершить работу, закройте соединение после последней отправки (если есть).
  3. Если вы хотите нормально закрыть соединение, отключите соединение (с помощью SHUT_WR, и если вам не нужно получать данные после этой точки, с помощью SHUT_RD), и дождитесь получения данных размера 0, а затем закройте разъем.
  4. В любом случае, если возникла другая ошибка (например, тайм-аут), просто закройте сокет.

Идеальные реализации для SHUT_RD и SHUT_WR

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

Если стек TCP получает завершение только с помощью SHUT_RD, он должен отмечать это соединение, поскольку больше ожидаемых данных не ожидается. Любые ожидающие и последующие запросы на read (независимо от того, какой из потоков они находятся) будут затем возвращаться с нулевым размером результата. Тем не менее, соединение по-прежнему активно и полезно — вы все равно можете получать данные OOB, например. Кроме того, ОС будет удалять любые данные, которые он получает для этого соединения. Но это все, никакие пакеты не будут отправлены на другую сторону.

Если стек TCP получает завершение только с помощью SHUT_WR, он должен отмечать это соединение, поскольку больше не может быть отправлено данных. Все ожидающие запросы на запись будут завершены, но последующие запросы на запись не удастся. Кроме того, пакет FIN будет отправлен на другую сторону, чтобы сообщить, что у нас больше нет данных для отправки.

29 Milan [2010-11-12 12:05:00]

Есть некоторые ограничения с close() , которые можно избежать, если вместо этого использовать shutdown() .

close() завершает оба направления в TCP-соединении. Иногда вы хотите сообщить другой конечной точке, что вы закончили с отправкой данных, но все же хотите получать данные.

close() уменьшает счетчик ссылок дескрипторов (поддерживается в записи таблицы файлов и подсчитывает количество открытых в данный момент дескрипторов, ссылающихся на файл/сокет) и не закрывает сокет/файл, если дескриптор не равен 0. Это означает что если вы используете forking, очистка происходит только после того, как счетчик ссылок падает до 0. С помощью shutdown() можно инициировать обычную последовательность TCP, игнорируя счетчик ссылок.

int how может быть:

SHUT_RD или 0 Дальнейшее получение запрещается

SHUT_WR или 1 Дальнейшие отправки запрещены

SHUT_RDWR или 2 Дальнейшие отправки и получения запрещены

Это может быть специфично для платформы, я как-то сомневаюсь в этом, но в любом случае лучшее объяснение, которое я видел, это здесь, на этой странице msdn, где они объясняют остановку, параметры задержки, закрытие сокетов и последовательности завершения соединения.

В заключение, используйте shutdown для отправки последовательности выключения на уровне TCP и используйте close, чтобы освободить ресурсы, используемые структурами данных сокета в вашем процессе. Если вы не указали явную последовательность выключения к тому времени, когда вы назовете «закрыть», тогда вы инициируете для вас.

6 Toby [2010-11-15 11:56:00]

У меня также был успех в Linux, используя shutdown() с одного pthread, чтобы принудительно заблокировать еще один pthread, заблокированный в connect() .

В других ОС (по крайней мере, по OSX) я обнаружил, что вызов close() был достаточно, чтобы получить connect() сбой.

«shutdown() фактически не закрывает дескриптор файла — он просто меняет удобство использования. Чтобы освободить дескриптор сокета, вам нужно использовать функцию close(). 1

Закрыть

Когда вы закончите использовать сокет, вы можете просто закрыть его дескриптор файла с закрытием; Если есть все еще данные, ожидающие передачи по соединению, обычно закрываются попытки завершить эту передачу. Вы можете управлять этим поведением, используя опцию сокета SO_LINGER, чтобы указать период ожидания; см. Параметры разъема.

ShutDown

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

Функция выключения отключает подключение разъема. В его аргументе указано, какое действие нужно выполнить: 0 Прекратите прием данных для этого сокета. Если поступают дополнительные данные, отклоните его. 1 Не пытайтесь передать данные из этого сокета. Отбросьте любые данные, ожидающие отправки. Прекратите искать подтверждение уже отправленных данных; Не возвращайте его, если он потерян. 2 Остановите прием и передачу.

Илон Маск рекомендует:  Предопределённые константы yp

Возвращаемое значение равно 0 при успешном завершении и -1 при ошибке.

0 simpx [2015-09-17 09:06:00]

close отправит пакет fin и немедленно уничтожит fd, когда сокет не будет использоваться совместно с другими процессами.

shutdown SHUT_RD, процесс все еще может возвращать данные из сокета, но recv будет возвращать 0, если буфер TCP пуст. После того как одноранговое сообщение отправит больше данных, recv снова вернет данные.

shutdown SHUT_WR отправит фин-пакет, чтобы указать, что дальнейшие отправки запрещены. одноранговый узел может возвращать данные, но он будет recv 0, если его буфер TCP пуст

shutdown SHUT_RDWR (равный использованию как SHUT_RD, так и SHUT_WR) отправит первый пакет, если peer отправит больше данных.

socket_shutdown

socket_shutdown — выключает получение, отправку с сокета или и то, и другое.

Описание

bool socket_shutdown (resource socket [, int how])

Эта функция — ЭКСПЕРИМЕНТАЛЬНАЯ. Поведение, имя и всё остальное, что задокументировано для данной функции может быть изменено в будущих релизах РНР без предупреждения. Вы можете использовать эту функцию только на свой страх и риск.

Предупреждение!

Эта функция в настоящее время ещё не задокументирована; имеется только список аргументов.

Socket.shutdown против socket.close

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

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

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

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

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

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

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

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

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

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

Пропуск выключения может привести к задержке сокета в стеке ОС до тех пор, пока соединение не будет закрыто изящно.

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

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

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

Разница между Socket :: close () и StreamSocket :: shutdown ()

При использовании Poco’s StreamSocket класс, и вы хотите закрыть сокетное соединение, из документации Poco и реализаций функций неясно, Socket::close() или же StreamSocket::shutdown() будет наиболее подходящей функцией для вызова. На платформах, где они, по-видимому, пересылаются в функции POSIX, справочную страницу для shutdown() заявляет, что отправка / получение будет остановлена, но ничего не говорит о самом соединении. Могу ли я быть уверенным, что close() по сути, будет надмножеством того, что shutdown() делает и, следовательно, close() является более подходящим для вызова? Если да, то есть ли пример сценария, в котором shutdown() будет более подходящим вызов?

Решение

shutdown Функция отключает либо отправляющую сторону соединения, принимающую сторону соединения, либо и то, и другое. close Функция просто закрывает сокет и не обязательно влияет на соединение. Однако, если соединение не имеет ссылок (потому что вы close d последний), то операционная система отключит соединение.

Другие решения

Разъемы POCO — очень тонкий слой поверх разъемов BSD

Поэтому POCO-сокеты принимают семантику BSD-сокетов для close() а также shutdown() ,

close() предотвратит чтение / запись на удаленном сокете в то время как shutdown() дает вам больше контроля над тем, какой конец должен быть отрезан. (что объясняет наличие StreamSocket::shutdownSend() а также StreamSocket::shutdownReceive() рядом StreamSocket::shutdown() )

РЕДАКТИРОВАТЬ: не забудьте проверить Комментарий Дэвида Шварца о точности руководства Биджа относительно фактических последствий close() ,

socket_shutdown

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

socket_shutdown — Завершает работу сокета на получение и/или отправку данных

Описание

Функция socket_shutdown() позволяет вам остановить передачу поступающих, исходящих или всех данных (по умолчанию) через сокет socket

Ассоциированный буфер, или буфферы, могут быть освобождены, а могут и нет.

Список параметров

Действующий ресурс сокета, созданный при помощи функции socket_create() .

Значение параметра how может быть одним из следующих:

Предупреждение!
возможные значения для параметра how
Завершает чтение из сокета
1 Завершает запись в сокет
2 Завершает чтение и запись в сокет

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

User Contributed Notes 4 notes

In this case, the TCP client is gracefully disconnected from the server

// create for tcp
$sock = socket_create ( AF_INET , SOCK_STREAM , getprotobyname ( ‘tcp’ ));
socket_bind ( $sock , ‘127.0.0.1’ , 5200 );
socket_listen ( $sock , 1024 );
$fp = fopen ( ‘./socket_shutdown.php’ , ‘rb’ );
$clnt_sock = socket_accept ( $sock );

while(! feof ( $fp )) <
$str = fread ( $fp , BUF_SIZE );
socket_write ( $clnt_sock , $str , BUF_SIZE );
>

$eof = «\n» ;
socket_write ( $clnt_sock , $eof , strlen ( $eof ));

//disconnect output stream(断开输入流)
socket_shutdown ( $clnt_sock , 1 );
$ret = socket_read ( $clnt_sock , 100 );
printf ( «Message from client:%s\n» , $ret );
socket_close ( $clnt_sock );
socket_close ( $sock );
?>

// for tcp-client
$clnt_sock = socket_create ( AF_INET , SOCK_STREAM , getprotobyname ( ‘tcp’ ));
socket_connect ( $clnt_sock , ‘127.0.0.1’ , 5200 );
while (( $cnt = @ socket_read ( $clnt_sock , 10 , PHP_NORMAL_READ )) !== false ) <
file_put_contents ( ‘./receive.data’ , $cnt , FILE_APPEND );
>
print «receive file data» . PHP_EOL ;
socket_write ( $clnt_sock , «Tank you» );
socket_close ( $clnt_sock );
?>

Shutdown and SOL_TCP:
= socket_create ( AF_INET , SOCK_STREAM , SOL_TCP );
socket_shutdown ( $a , 2 )
?>
PHP Warning: socket_shutdown(): unable to shutdown socket [107]: Transport endpoint is not connected

Shutdown and SOL_UDP:
= socket_create ( AF_INET , SOCK_STREAM , SOL_UDP );
socket_shutdown ( $a , 2 )
?>
PHP Warning: socket_shutdown(): unable to shutdown socket [107]: Transport endpoint is not connected

Conclusion: if you are not actually connected, shutdown will fails with socket_error = 107, Transport endpoint is not connected. This is true for both TPC and UDP connection (which is suprising, UDP being a connectionless protocol). This is true no matter the value set for the how parameter.

socket.shutdown против socket.close

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

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

7 ответов

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

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

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

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

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

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

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

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

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

Пропуск выключения может привести к зависанию сокета в стеке ОС до тех пор, пока соединение не будет закрыто изящно.

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

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

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

Разве этот код выше не так?

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

Согласно http: // blog. netherlabs. nl / Articles / 2009/01/18 / Невероятно надежная страница нужно ждать между выключением и закрытием, пока чтение не вернет 0.

Что такое код socket_shutdown

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

А ты не делай вызов bind() предварительно. Для клиента он необязателен. А если он все же нужен, то, для одной и той же машины, номера сокутов действительно должны быть различны и сокет с этим номером не должен быть занят даже другим приложением.

Добавлено:
Извини, невнимательно прочитал сообщение, ты перезапускаешь клиент, а не запускаешь еще один. Но все равно попробуй bind() убрать, если он есть, может у тебя сокет не освобождаеется. В клиенте вызов closesocket() при завершении есть?

close vs shutdown socket?

In C, I understood that if we close a socket, it means the socket will be destroyed and can be re-used later.

How about shutdown? The description said it closes half of a duplex connection to that socket. But will that socket be destroyed like close system call?

8 Answers 8

This is explained in Beej’s networking guide. shutdown is a flexible way to block communication in one or both directions. When the second parameter is SHUT_RDWR , it will block both sending and receiving (like close ). However, close is the way to actually destroy a socket.

With shutdown , you will still be able to receive pending data the peer already sent (thanks to Joey Adams for noting this).

None of the existing answers tell people how shutdown and close works at the TCP protocol level, so it is worth to add this.

A standard TCP connection gets terminated by 4-way finalization:

  1. Once a participant has no more data to send, it sends a FIN packet to the other
  2. The other party returns an ACK for the FIN.
  3. When the other party also finished data transfer, it sends another FIN packet
  4. The initial participant returns an ACK and finalizes transfer.

However, there is another «emergent» way to close a TCP connection:

  1. A participant sends an RST packet and abandons the connection
  2. The other side receives an RST and then abandon the connection as well

In my test with Wireshark, with default socket options, shutdown sends a FIN packet to the other end but it is all it does. Until the other party send you the FIN packet you are still able to receive data. Once this happened, your Receive will get an 0 size result. So if you are the first one to shut down «send», you should close the socket once you finished receiving data.

On the other hand, if you call close whilst the connection is still active (the other side is still active and you may have unsent data in the system buffer as well), an RST packet will be sent to the other side. This is good for errors. For example, if you think the other party provided wrong data or it refused to provide data (DOS attack?), you can close the socket straight away.

My opinion of rules would be:

  1. Consider shutdown before close when possible
  2. If you finished receiving (0 size data received) before you decided to shutdown, close the connection after the last send (if any) finished.
  3. If you want to close the connection normally, shutdown the connection (with SHUT_WR, and if you don’t care about receiving data after this point, with SHUT_RD as well), and wait until you receive a 0 size data, and then close the socket.
  4. In any case, if any other error occurred (timeout for example), simply close the socket.

Ideal implementations for SHUT_RD and SHUT_WR

The following haven’t been tested, trust at your own risk. However, I believe this is a reasonable and practical way of doing things.

If the TCP stack receives a shutdown with SHUT_RD only, it shall mark this connection as no more data expected. Any pending and subsequent read requests (regardless whichever thread they are in) will then returned with zero sized result. However, the connection is still active and usable — you can still receive OOB data, for example. Also, the OS will drop any data it receives for this connection. But that is all, no packages will be sent to the other side.

If the TCP stack receives a shutdown with SHUT_WR only, it shall mark this connection as no more data can be sent. All pending write requests will be finished, but subsequent write requests will fail. Furthermore, a FIN packet will be sent to another side to inform them we don’t have more data to send.

Что такое код socket_shutdown

Опубликовано: Октябрь 2020

Отключает передачу и прием на Socket.

Пространство имен: System.Net.Sockets
Сборка: System (в System.dll)

Параметры

Один из SocketShutdown значений, указывающий операцию, которая больше не будет разрешен.

Произошла ошибка при попытке доступа к сокету. Дополнительные сведения см. в разделе «Примечания».

При использовании ориентированного на подключение Socket, всегда вызывать Shutdown метод перед закрытием Socket. Это гарантирует, что все данные входящему и исходящему на подключенный сокет, до его закрытия.

Вызов Close метод, чтобы освободить все управляемые и неуправляемые ресурсы, связанные с Socket. Не пытайтесь повторно использовать Socket после закрывающего тега.

В следующей таблице показаны SocketShutdown значений перечисления, которые являются допустимыми для how параметр.

Запретить передачу на этом Socket.

Запретить прием на этом Socket.

Отключение отправки и получения по этому Socket.

Параметр how для Send Указывает, что последующие вызовы Send не допускаются. Если вы используете установления Socket, указав Send не будет действовать.

Параметр how для Receive Указывает, что последующие вызовы Receive не допускаются. Это не влияет на нижнем уровне протокола. Если используется протокол с установлением соединения, соединение закрывается при наличии одного из следующих условий после вызова Shutdown :

Данные являются во входном буфере сети, ожидающие приема.

Получены дополнительные данные.

Если используется протокол без установления соединения, датаграммы принимаются и в очередь. Тем не менее если буферное пространство для дополнительных входных датаграмм, они будут уничтожены и ошибка не возвращается отправителю. С помощью Shutdown для установления Socket не рекомендуется.

Параметр how для Both отключает обоих передачу и прием, как описано выше.

Exception Condition
SocketException

При получении SocketException при вызове Shutdown метода, используйте свойство для получения определенного кода ошибки. Получив этот код, см. версию Windows Sockets 2 API документации по кодам ошибок в библиотеке MSDN подробное описание ошибки.

Примечание

Данный член генерирует сведения трассировки, если в приложении включена трассировка сети. Для получения дополнительной информации см. Трассировка сети в .NET Framework.

Разъем Shutdown: когда я должен использовать SocketShutdown.Both

Я считаю , что последовательность выключения выглядит следующим образом (как описано здесь ):

При использовании ориентированного на соединение Socket , всегда вызывать Shutdown метод перед закрытием Socket . Это гарантирует , что все данные передаются и принимаются на подключенный сокет до его закрытия.

Это подразумевает , что если я буду использовать Shutdown(SocketShutdown.Both) любые данные , которые еще не были получены, все еще могут быть израсходованы. Чтобы проверить это:

  • Я непрерывно передавать данные клиента ( с помощью Send в отдельном потоке).
  • Клиент выполняется Shutdown(SocketShutdown.Both) .
  • BeginReceive Обратный вызов на сервере выполняет, однако, EndReceive вызывает исключение: существующее соединение было принудительно закрыто удаленным узлом . Это означает , что я не могу получить 0 возвращаемое значение и , в свою очередь вызова Shutdown .

В соответствии с просьбой, я разместил на стороне сервера код ниже (это завернутые в форме Windows и она была создана только в качестве эксперимента). В моем тестовом сценарии я не видел CLOSE_WAIT состояние в TCPView , как я обычно делал , не посылая непрерывные данные. Так что потенциально я сделал что — то не так , и я прервав последствия неправильно. В другом эксперименте:

  • Клиент подключается к серверу.
  • Клиент выполняет Shutdown(SocketShutdown.Both) .
  • Сервер получает подтверждение завершения работы и посылает некоторые данные в ответ. Сервер также выполняет Shutdown .
  • Клиент получает данные от сервера , но следующий BeginReceive не допускаются: Просьба отправлять или принимать данные не была засчитана , так как сокет уже был закрыт в этом направлении с предыдущим вызовом отключения

В этом случае, я по — прежнему ожидает 0 возвращаемое значение EndReceive для Close сокета. Означает ли это , что я должен использовать Shutdown(SocketShutdown.Send) вместо этого? Если да, то когда следует использовать Shutdown(SocketShutdown.Both) ?

Код из первого эксперимента:

Это подразумевает, что если я использую Shutdown (SocketShutdown.Both), любые данные, которые еще не были получены, все еще могут быть потреблены

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

Существующее соединение было принудительно закрыто удаленным хостом

Это не должно случиться. Почтовый индекс.

Значит ли это, что я должен использовать Shutdown (SocketShutdown.Send) вместо этого?

Если вы хотите продолжать Получать почему вы выключая прием? Только не делайте этого. Только выключить передачу.

Если да, то когда следует использовать Shutdown (SocketShutdown.Both)?

Когда вы ни хотели получить, ни отправить. Вы можете уточнить, почему это не очевидно для вас? Может быть, есть недоразумение, или я не понял вопрос.

Илон Маск рекомендует:  Faq определение системной информации
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Примечание