2009-05-27 4 views
2

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

[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 на стороне клиента?

Спасибо.

ответ

5

Согласно документации для Socket.Connected:

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

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

+0

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

1

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

+0

Что произойдет, если соединение клиента прерывается? (т. е. не изящный вариант отказа :(, сервер будет застрял на прием нет?) – Drahakar

+0

Я не знаю .NET socket API, но представляю, что вы получите исключение. Исходный C API возвращается -1, а конкретная ошибка зависит о том, что именно произошло - получен RST, тайм-аут и т. д. –

+0

Нет, это то, о чем я думал, но когда я пытаюсь отправить свою вторую нить на закрытом сокете, он возвращает 0, без исключения, все кажется прекрасным – Drahakar

0
bool part1 = s.Poll(1000, SelectMode.SelectRead); 
bool part2 = (s.Available == 0); 
if (part1 & part2) 
{//connection is closed 
} 
Смежные вопросы