Я провел некоторую работу над библиотекой сокетов, которая используется для передачи медицинских изображений в .NET за последний год или около того. Вначале нам было трудно определить, когда сокет отключился, но, наконец, мы нашли стабильное решение.
Наше приложение использует NetworkStream для чтения / записи в сокет. У нас есть похожая на вас цепочка, которая создается при поступлении нового соединения и используется для чтения и записи данных в сеть. Мы вызываем метод ниже для опроса, когда данные поступили или когда соединение было закрыто. Метод может быть настроен на использование более длительного тайм-аута, если вы не хотите опрашивать. Когда мы знаем, что данные доступны, мы читаем из объекта NetworkStream.
Ключевым моментом ниже является нулевой байт Send на сокете, который, кажется, обнаруживает, когда сокет выключился, как упомянуто в комментариях. Метод OnNetworkError просто вызывается, чтобы запустить отключаемый поток.
Стив
protected override bool NetworkHasData()
{
if (_socket == null)
return false;
// Tells the state of the connection as of the last activity on the socket
if (!_socket.Connected)
{
OnNetworkError(null, true);
return false;
}
// This is the recommended way to determine if a socket is still active, make a
// zero byte send call, and see if an exception is thrown. See the Socket.Connected
// MSDN documentation. Only do the check when we know there's no data available
try
{
List readSockets = new List();
readSockets.Add(_socket);
Socket.Select(readSockets, null, null, 100000);
if (readSockets.Count == 1)
{
if (_socket.Available > 0)
return true;
OnNetworkError(null, true);
return false;
}
_socket.Send(new byte[1], 0, 0);
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
if (!e.NativeErrorCode.Equals(10035))
OnNetworkError(e, true);
}
return false;
}