2014-09-29 3 views
1

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

Вот код ..

// 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(); 
     } 

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

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

+0

Отправьте «PING», дождитесь «PONG» –

+0

@AlexK. Мне жаль, что я не получил вас –

ответ

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 
} 

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

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 сообщение, символ новой строки «\ п» терминатор характер и «0005» длина сообщения за исключением т он тип сообщения.

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

+0

Можете ли вы дать мне пример или соединение psudocode с моим кодом в сообщении. Фактически я новичок в этом поле, поэтому не получаю понятных понятий –

+0

@shubhamHegdey Добавлен пример. Надеюсь, вы сможете добиться определенного прогресса. –

Смежные вопросы