Подтвердить что ты не робот

Самый быстрый способ протестировать интернет-соединение

С# 2008 SP1

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

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

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

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

Таким образом, для этого требуются следующие условия:

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

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

Мне нужно использовать свойство timeout. Поэтому нельзя использовать класс 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;
            }

======== Редактировать, используя p\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);
4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

Ответ 3

У меня была аналогичная ситуация, когда мы собирались сделать 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();
    }

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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