Как проверить, закрыто ли соединение TcpClient?

Я играю с TcpClient, и я пытаюсь понять, как сделать свойство Connected ложным при отключении соединения.

Я пробовал делать

NetworkStream ns = client.GetStream(); ns.Write(new byte[1], 0, 0); 

Но он все равно не покажет мне, отключен ли TcpClient. Как бы вы это сделали, используя TcpClient?

7 Solutions collect form web for “Как проверить, закрыто ли соединение TcpClient?”

Я бы не рекомендовал вам попробовать писать только для тестирования сокета. И не переставляйте также свойство Connected .NET.

Если вы хотите узнать, активна ли удаленная конечная точка, вы можете использовать TcpConnectionInformation:

 TcpClient client = new TcpClient(host, port); IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections().Where(x => x.LocalEndPoint.Equals(client.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(client.Client.RemoteEndPoint)).ToArray(); if (tcpConnections != null && tcpConnections.Length > 0) { TcpState stateOfConnection = tcpConnections.First().State; if (stateOfConnection == TcpState.Established) { // Connection is OK } else { // No active tcp Connection to hostName:port } } client.Close(); 

Смотрите также:
TcpConnectionInformation на MSDN
IPGlobalProperties на MSDN
Описание состояний TcpState
Netstat в Википедии


И здесь это как метод расширения на TcpClient.

 public static TcpState GetState(this TcpClient tcpClient) { var foo = IPGlobalProperties.GetIPGlobalProperties() .GetActiveTcpConnections() .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint)); return foo != null ? foo.State : TcpState.Unknown; } 

Насколько я знаю / помню, нет способа проверить, подключен ли сокет, кроме чтения или записи на него.

Я вообще не использовал TcpClient, но class Socket вернет 0 из вызова Read, если удаленный конец был отключен изящно. Если удаленный конец не выключается изящно [я думаю], вы получаете исключение тайм-аута, не можете вспомнить тип извините.

Использование кода типа if(socket.Connected) { socket.Write(...) } создает условие гонки. Вам лучше просто вызвать socket.Write и обработать исключения и / или отключить.

Ответ @ uriel отлично подходит для меня, но мне нужно было закодировать его в C ++ / CLI, что было не совсем тривиально. Вот (примерно эквивалентный) код C ++ / CLI, с несколькими проверками надежности, добавленными для хорошей оценки.

 using namespace System::Net::Sockets; using namespace System::Net::NetworkInformation; TcpState GetTcpConnectionState(TcpClient ^ tcpClient) { TcpState tcpState = TcpState::Unknown; if (tcpClient != nullptr) { // Get all active TCP connections IPGlobalProperties ^ ipProperties = IPGlobalProperties::GetIPGlobalProperties(); array ^ tcpConnections = ipProperties->GetActiveTcpConnections(); if ((tcpConnections != nullptr) && (tcpConnections->Length > 0)) { // Get the end points of the TCP connection in question EndPoint ^ localEndPoint = tcpClient->Client->LocalEndPoint; EndPoint ^ remoteEndPoint = tcpClient->Client->RemoteEndPoint; // Run through all active TCP connections to locate TCP connection in question for (int i = 0; i < tcpConnections->Length; i++) { if ((tcpConnections[i]->LocalEndPoint->Equals(localEndPoint)) && (tcpConnections[i]->RemoteEndPoint->Equals(remoteEndPoint))) { // Found active TCP connection in question tcpState = tcpConnections[i]->State; break; } } } } return tcpState; } bool TcpConnected(TcpClient ^ tcpClient) { bool bTcpConnected = false; if (tcpClient != nullptr) { if (GetTcpConnectionState(tcpClient) == TcpState::Established) { bTcpConnected = true; } } return bTcpConnected; } 

Надеюсь, это поможет кому-то.

Я создал эту функцию и работал для меня, чтобы проверить, все ли клиент подключен к серверу.

 ///  /// THIS FUNCTION WILL CHECK IF CLIENT IS STILL CONNECTED WITH SERVER. ///  /// FALSE IF NOT CONNECTED ELSE TRUE public bool isClientConnected() { IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties(); TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections(); foreach (TcpConnectionInformation c in tcpConnections) { TcpState stateOfConnection = c.State; if (c.LocalEndPoint.Equals(ClientSocket.Client.LocalEndPoint) && c.RemoteEndPoint.Equals(ClientSocket.Client.RemoteEndPoint)) { if (stateOfConnection == TcpState.Established) { return true; } else { return false; } } } return false; } 

Решение Peter Wone и uriel очень приятно. Но вам также нужно проверить удаленную конечную точку, так как вы можете иметь несколько открытых подключений к вашей локальной конечной точке.

  public static TcpState GetState(this TcpClient tcpClient) { var foo = IPGlobalProperties.GetIPGlobalProperties() .GetActiveTcpConnections() .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(tcpClient.Client.RemoteEndPoint) ); return foo != null ? foo.State : TcpState.Unknown; } 

В моем случае я отправлял некоторую команду на сервер (работающий на виртуальной машине на том же компьютере) и ожидая ответа. Однако, если сервер неожиданно остановился во время ожидания, я не получил никаких уведомлений. Я пробовал возможности, предлагаемые другими плакатами, но и не работал (он всегда говорил, что сервер все еще подключен). Для меня единственное, что работает, это написать 0 байтов в stream:

 var client = new TcpClient(); //... open the client var stream = client.GetStream(); //... send something to the client byte[] empty = { 0 }; //wait for response from server while (client.Available == 0) { //throws a SocketException if the connection is closed by the server stream.Write(empty, 0, 0); Thread.Sleep(10); } 

Попробуйте это, это работает для меня

 private void timer1_Tick(object sender, EventArgs e) { if (client.Client.Poll(0, SelectMode.SelectRead)) { if (!client.Connected) sConnected = false; else { byte[] b = new byte[1]; try { if (client.Client.Receive(b, SocketFlags.Peek) == 0) { // Client disconnected sConnected = false; } } catch { sConnected = false; } } } if (!sConnected) { //--Basically what you want to do afterwards timer1.Stop(); client.Close(); ReConnect(); } } 

я использовал Таймер, потому что я хотел проверить состояние соединения с регулярным интервалом, а не в LOOP с кодом прослушивания [я чувствовал, что это замедляет процесс отправки)

  • Что значит связать сокет многоадресной рассылки (UDP)?
  • Клиент сервера посылает / получает простой текст
  • C # Begin / EndReceive - как читать большие данные?
  • Передача структуры через Sockets в C
  • Socket.io + Node.js Запрос на перекрестный запрос заблокирован
  • Как обнаружить ближайший боковой разъем?
  • как получить файл передачи между клиентом и сервером с помощью java socket
  • Как установить тайм-аут блокировки сокетов в boost asio?
  • Как работает функция accept API ()?
  • Передача изображения OpenCV на C ++ через сокет
  • Асинхронный ввод-вывод в Java?
  • Давайте будем гением компьютера.