Проблема состояния подключения TcpClient в сети не работает

У меня есть TcpClient, который я подключаю к машине, и все работает нормально. Теперь еще один шаг. Я хочу отслеживать состояние подключения в течение очень 60 секунд с помощью таймера. Согласно базовому исследованию темы, которую я узнал что нет прямого способа проверить это. Поэтому я попытался получить его по ответу на недавнее сообщение, отправленное на машину, когда приложение выходит из сети.

Вот код..

 // Find out whether the socket is connected to the remote host.

 //Send a message to Machine
 try
 {
  byte[] notify = Encoding.ASCII.GetBytes("Hello");
  stream.Write(notify, 0, notify.Length);     
 }catch { }

 //Check if it reached to machine or failed 
 bool getConnectionStatus = client.Connected;

 if (getConnectionStatus == true)
     {
         //Do nothing
     }
 else
     {
        //Stop the thread
        _shutdownEvent.WaitOne(0);
        _thread.Abort();

         //Start Again
         _thread = new Thread(DoWork);
         _thread.Start();
      }

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

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


person shubham Hegdey    schedule 29.09.2014    source источник
comment
Отправьте PING, дождитесь PONG   -  person Alex K.    schedule 29.09.2014
comment
@АлексК. Извини, я не понял тебя   -  person shubham Hegdey    schedule 29.09.2014


Ответы (1)


Под капотом операция Write просто отправляет данные на сетевой уровень; вы можете получить результат «успех» до того, как будет предпринята попытка передачи данных. Сетевой уровень может даже задержать отправку данных на некоторое время, если данные малы, пытаясь отправить один пакет из нескольких сообщений одновременно.

На что Алекс К. в двух словах сказал, что самый надежный способ проверить сетевое соединение — дождаться ответа. Если такой ответ не получен в течение определенного периода времени, соединение теряется.

Допустим, вы продолжаете использовать «Привет», и сервер должен ответить «Да!». На стороне клиента вы можете расширить свой текущий код с помощью:

try
{
    byte[] notify = Encoding.ASCII.GetBytes("Hello");
    stream.Write(notify, 0, notify.Length);
    byte[] notifyResult = new byte[5];
    int bytesRead = stream.Read(notifyResult, 0, 5);
    if (bytesRead == 0)
    {
        // No network error, but server has disconnected
    }

    // Arriving here, notifyResult should contain ASCII "Yeah!" 
}
catch (SocketException)
{
    // Network error
}

На сервере вы должны распознать отправленное «Привет» и просто ответить «Да!». Я не знаю, что сейчас делает ваш сервер, но это может быть чем-то похожим на:

switch (receivedMessage)
{
    case "Hello":
        stream.Write(Encoding.ASCII.GetBytes("Yeah!"), 0, 5);
        break;
}

Обратите внимание, что вам следует рассмотреть возможность упаковки ваших сообщений в информационные пакеты, т.е.:

<Message Type> <Message> <Terminator Character>
ie. "KHello\n"

Or

<Size of Message> <Message Type> <Message> 
ie. "0005KHello" 

Где тип сообщения «K» — это сообщение Keep-alive, новая строка «\n» — символ конца, а «0005» — длина сообщения без учета типа сообщения.

Таким образом, сервер всегда сможет определить, получил ли он полное сообщение, а тип сообщения может указать, было ли отправлено «Hello» в виде данных или в виде пакета проверки активности.

person C.Evenhuis    schedule 29.09.2014
comment
Не могли бы вы привести пример или подключение псевдокода к моему коду в сообщении. На самом деле я новичок в этой области, поэтому не понимаю термины четко - person shubham Hegdey; 29.09.2014
comment
@shubhamHegdey Добавил пример. Я надеюсь, что вы можете добиться некоторого прогресса с ним. - person C.Evenhuis; 29.09.2014