2009-05-09 20 views
21

C# 2008 SP1Самый быстрый способ протестировать подключение к Интернету

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

Итак, хочу, чтобы я использовал класс httpWebRequest для подключения к нашему сайту клиентов. Если ответ в порядке, то подключение к Интернету может продолжаться.

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

Однако, когда я просматриваю их веб-сайт, загрузка страницы занимает меньше секунды. Но занимает слишком много времени, когда я использую класс HttpWebRequest

Так требования для этого являются:

Когда-нибудь прокси будет использоваться в офисе клиента. Я не могу использовать класс TCPClient (не имеет свойства прокси).

Прокси не поддерживает SOCKS, поэтому не может использовать класс Sockets.

Мне нужно использовать свойство таймаута. Поэтому нельзя использовать класс WebClient. Это связано с тем, что программный телефон замерзнет, ​​пока не будет получен ответ. Итак, тайм-аут через несколько секунд.

Таким образом, единственное, что я могу представить, это класс HttpWebRequest.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.xxxxxxxxx.com"); 
      request.Timeout = 5000; 
      request.Credentials = CredentialCache.DefaultNetworkCredentials; 
      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

      if (response.StatusCode == HttpStatusCode.OK) 
      { 
       Console.WriteLine("IsSIPServerAvailable: " + response.StatusCode); 
       isAvailable = true; 
      } 

======== Редактирование с помощью р \ Invoke ====

[DllImport("wininet.dll", CharSet = CharSet.Auto)] 
    private extern static bool InternetGetConnectedState(ref InternetConnectionState_e lpdwFlags, int dwReserved); 

[Flags] 
    enum InternetConnectionState_e : int 
    { 
     INTERNET_CONNECTION_MODEM = 0x1, 
     INTERNET_CONNECTION_LAN = 0x2, 
     INTERNET_CONNECTION_PROXY = 0x4, 
     INTERNET_RAS_INSTALLED = 0x10, 
     INTERNET_CONNECTION_OFFLINE = 0x20, 
     INTERNET_CONNECTION_CONFIGURED = 0x40 
    } 

// In function for checking internet 
InternetConnectionState_e flags = 0;   
bool isConnected = InternetGetConnectedState(ref flags, 0); 

ответ

16

Попробуйте использовать P/Invoke для вызова InternetGetConnectedState. Это должно сказать вам, настроено ли соединение. Затем вы можете попробовать проверить конкретное соединение с вашим сервисом, используя InternetCheckConnection. Это (иногда) быстрее, чем подключение напрямую, но я бы проверил его, чтобы убедиться, что это лучше, чем просто полное соединение вверх.

+3

Недостатком этого (ИМО) является то, что он сообщает только, подключен ли компьютер к «интернету в целом». Это лишь несколько свидетельствует о том, сможете ли вы получить конкретную услугу, которой вы пользуетесь. Лучший способ сделать это, IMO, - это подключиться к этой самой услуге. Конечно, это не будет гарантировать, что он по-прежнему будет действовать через секунду, но я думаю, что это лучший показатель, если это возможно. (В некоторых случаях это не так, например, если просто подключение накладывает какую-то плату.) –

+1

Я отредактировал мой код для p/Invoke. Однако, это говорит мне, подключена ли ЛВС к моему компьютеру (подключен или выключен). Однако он не может сказать мне, есть ли у меня активное интернет-соединение (просматривайте Интернет). – ant2009

+0

@robUK: Я отредактировал свой ответ, чтобы включить вызов в InternetCheckConnection. Это еще один P/Invoke, который вы можете попробовать - он должен сказать вам, доступен ли этот конкретный URL-адрес, но я считаю, что он немного быстрее, чем пытаться подключить соединение самостоятельно. –

11

Что такое программный телефон, предназначенный для его реального общения? Это происходит через HTTP/HTTPS на тот же веб-сайт? Если это так, это абсолютно правильный путь - следующий шаг - это выяснить, почему это так долго.

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

Если ваше фактическое приложение будет подключаться в другом месте, то это также проверит ваш тест. В принципе, сделайте его как можно ближе к реальному.

Из интереса вы говорите, что это приложение «софтфон» - это действительно работает на телефон какого-либо описания, используя компактный фреймворк или это настольное приложение?

+0

Здравствуйте. Его рабочий стол работает, который может работать на 2000, XP и Vista. Это для информации об использовании оператора. Я забыл об этом. Сервер SIP находится на одном сервере. Тем не менее, я могу подключаться с использованием протокола SIP и потоковой передачи с использованием RTP. – ant2009

+0

Если вы собираетесь подключиться к SIP позже, почему бы не подключиться к SIP для теста? Есть ли какой-либо запрос SIP без операции, который вы можете сделать? –

+0

Я просматриваю некоторые запросы SIP. Мне также нравится вариант P/invoke ниже. Я думаю, что буду экспериментировать с обоими вариантами. Благодарю. – ant2009

2

Вы можете ссылаться на пространство имен Microsoft.VisualBasic.Devices, чтобы использовать делегат NetworkAvailableEventHandler и класс Network. Я использую свойство Network.IsAvailable и Network.NetworkAvailabilityChanged, чтобы проверить, что сеть там (или затронута позже), а затем выполните HTTP GET на мой сервер, чтобы узнать, есть ли сервер.

Это помогает сообщать о проблеме немного более конкретно, вместо того, чтобы «не видеть сеть».

6

У меня была аналогичная ситуация, когда мы собирались сделать вызов WCF клиенту, и это займет слишком много времени, если клиент не был доступен (по какой-либо причине). То, что я сделал, это открыть сырой TCP-сокет для адреса клиента ... Это быстро не удается, если клиент не прослушивает порт (в вашем случае порт 80) и быстро завершается, если они есть.

Это дало мне самый быстрый и точный ответ, чтобы определить, смогу ли я связаться с конечной точкой, которую я пытался достичь. Единственная нижняя сторона этого заключается в том, что вы должны управлять таймаутом самостоятельно в сокете, потому что есть только опции для тайм-аутов отправки и получения, которые не подключаются.

Это идет что-то вроде этого ...

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

    try 
    { 
     IAsyncResult result = socket.BeginConnect("www.xxxxxxxxx.com", 80, null, null); 
     //I set it for 3 sec timeout, but if you are on an internal LAN you can probably 
     //drop that down a little because this should be instant if it is going to work 
     bool success = result.AsyncWaitHandle.WaitOne(3000, true); 

     if (!success) 
     { 
       throw new ApplicationException("Failed to connect server."); 
     } 

     // Success 
     //... 
    } 
    finally 
    { 
     //You should always close the socket! 
     socket.Close(); 
    } 

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

+0

Здравствуйте, спасибо за код. На самом деле я уже пробовал класс сокетов. Однако прокси-сервер, с которым я должен подключиться, не поддерживает протокол SOCKS.Если бы не прокси-сервер, это было бы отличным решением. – ant2009

+0

Извините, я пропустил это в вашем вопросе ... –

+0

ONiel, Спасибо. Я использовал TcpClient, и это было намного медленнее, чем этот метод. –

1

Лучше всего добавить ссылку на Microsoft.VisualBasic и добавить оператор using Microsoft.VisualBasic.Device, тогда вы можете использовать следующую строку кода для проверки подключения к любой сети вообще.

public static bool isConnectedToNetwork { 
    get { 
     Network network = new Network(); 
     return network.IsAvailable; 
    } 
} 
0

request.GetResponse()сам даст вам исключение, если имя хоста не может быть решена, хотя, так что вы можете положить Try-улов вокруг этого, поймать System.Net.WebException, и проверить его состояние ошибки в Status Недвижимость. Я не уверен, какие статусы точно не указывают на интернет; большинство ответов может быть также вызвано проблемами DNS или другими проблемами соединения.

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