Проблем със състоянието на връзката на 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
@AlexK. Съжалявам, че не те разбрах   -  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