2011-01-11 2 views
1

Я пишу программу связи с режимом c/s в C#, серверной и клиентской программе на другом компьютере. Сегодня после того, как клиент progarm подключился к серверному progarm, я вытащил кабель из сетевого адаптера (после этого клиентская и серверная программа ничего не сделала), произошло нечто странное. Я обнаружил, что сокет серверной программы все еще сохраняет статус соединения. и я использую команду "NetStat -a -n" для получения информации о сети и получать информацию, как следующее:Как получить статус сокета при отсоединении сетевого кабеля от сетевого адаптера

TCP 192.168.1.2:3645 192.168.1.3:1863 СОЗДАН

192.168.1.2 (IP-адрес сервера) 192.168.1.3 (IP-адрес клиента)

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

Пожалуйста, дайте мне несколько советов или решений.

Благодаря

+0

запомнить, socket.Connected (или IsConnected, я забыл) сообщит вам только статус сокета после последней команды. Поэтому, если ваша последняя команда была успешной, она вернет true. Если вы вытащите кабель, он будет оставаться верным, пока вы не попытаетесь его использовать, и что-то не удастся. – NibblyPig

ответ

4

Я думаю, что это можно решить, используя протокол TCP keepalive. refrence http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html

после подключения, установка гнездо фиксированный свойство. msdn сказать, что этот статус по умолчанию для коммутатора выключен, если установлено keepalive on on, socket автоматически проверяет состояние сети, а первое время проверки - через 2 часа после последней операции на сокете. но время может быть приближено к короткому. то после первой проверки сокет будет иметь время сервара. если соединение отключено или скончалось, сокет выдает исключение.

C# Источник:

uint dummy = 0; 
    byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; 
    //set keepalive on 
    BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); 
    //interval time between last operation on socket and first checking. example:5000ms=5s 
    BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); 
    //after first checking, socket will check serval times by 1000ms. 
    BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); 

    Socket socket = __Client.Client; 
    socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); 

Я проверил. Он работает нормально.

+0

Это работает как шарм и легко заслуживает 100 upvotes. – Toxantron

-1

Im немного не уверены, но если вы пытаетесь прочитать данные из розетки после того, как вы вытащили кабель он скажет вам, что его не подключен больше ..

+0

Спасибо много. Но я хочу со временем поймать исключение. потому что бизнес программы: Сервер отправляет команду клиенту и клиенту, получает команду и выполняет ее, а затем отправляет результат обратно. программа приема сервера асинхронна, поэтому, когда я вытаскиваю кабель, сервер не может получать какие-либо данные. – user571102

+0

без какого-либо кода, я не могу вам помочь .. но вы должны слушать данные, и это должно произойти, когда кабель вытащен ... – Peter

+0

Нет, если нет, если вы не установите таймер ожидания сокета, в котором в случае, когда все это скажет вам, что время ожидания истекло. Не почему. – EJP

2

Вы не можете. Единственным надежным способом проверки состояния соединения является передача данных по кабелю, поэтому: устраняйте сбои подключения во время отправки и получения и, при необходимости, периодически проверяйте состояние соединения с помощью какой-либо формы ping, если вы хотите, чтобы состояние соединения во время простоя периоды.

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