Используя System.Net.Socket, как мы можем узнать, когда удаленный сокет закрыт?

2

Итак, вот как идут дела:

[Server] Start
[Server] Socket.AcceptConnection
[Client] Start
[Client] Socket.Connect 
[Server] Receive //blocking
[Client] Send
[Server] Print
[Server] Receive
[Client] Close socket

Есть ли способ узнать, когда клиент закрыл соединение? В настоящее время я использую фальшивый пакетный трюк, как описано в MSDN, где в отдельном потоке я делаю

[Server] socket.Send(byte[], 0,0);

И я проверяю, не выбрасывает ли она какую-либо ошибку, но это не так, даже если клиент закрыл сокет.

P.S. Я действительно думаю, может быть, проблема, если у меня есть сокет на стороне сервера (TCP) и TcpClient на стороне клиента?

Спасибо.

Теги:
sockets

3 ответа

5
Лучший ответ

В соответствии с документами для Socket.Connected:

Значение свойства Connected отражает состояние соединения начиная с последней операции. Если вам необходимо определить текущий состояния соединения, неблокирующий, нулевой байтовый вызов. Если вызов возвращается успешно или выдает код ошибки WAEWOULDBLOCK (10035), то сокет все еще связанный; в противном случае сокет не будет более длинный.

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

  • 0
    Если вы получаете FIN, то последний получатель (обратный вызов или блокировка) должен иметь длину 0. Если вы получили это, то проверьте состояние сокета.
1

TCP-соединение должно возвращать 0, т.е. EOF, при чтении из сокета, на котором был получен FIN, но вам будет намного лучше разрабатывать ваш протокол, чтобы стороны говорили друг другу, когда время для отключения/закройте гнездо. Также игра с одним и тем же сокетом из нескольких потоков укусит вас - избегайте этого.

  • 0
    Что должно произойти, когда клиентское соединение прерывается? (т.е. нет опции gracefull fail :(, сервер зависнет при получении нет?)
  • 0
    Я не знаю API сокетов .NET, но думаю, вы получите исключение. Native C API возвращает -1, и конкретная ошибка зависит от того, что именно произошло - получено RST, истекло время ожидания и т. Д.
Показать ещё 2 комментария
0
bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = (s.Available == 0);
if (part1 & part2)
{//connection is closed
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню