处理网络断开

时间:2012-02-09 18:45:52

标签: c#

我正在尝试使用HttpWebRequest对象进行“长轮询”。

在我的C#应用​​程序中,我正在使用HttpWebRequest发出HTTP GET请求。然后,我等待beginGetResponse()的响应。我正在使用ThreadPool.RegisterWaitForSingleObject来等待响应,或者超时(1分钟后)。

我已将目标Web服务器设置为需要很长时间才能响应。所以,我有时间断开网络电缆。

发送请求后,我拔下网线。

有没有办法在发生这种情况时获得异常?所以我不必等待超时?

超时(来自RegisterWaitForSingleObject)在1分钟超时到期后发生,而不是异常。

有没有办法确定网络连接断开?目前,这种情况与Web服务器响应时间超过1分钟的情况无法区分。

3 个答案:

答案 0 :(得分:8)

我找到了解决方案:

在调用beginGetResponse之前,我可以在HttpWebRequest上调用以下内容:

req.ServicePoint.SetTcpKeepAlive( true, 10000, 1000)

我认为这意味着在10秒不活动后,客户端会将TCP“保持活动”发送到服务器。如果由于网络电缆被拔出而网络连接断开,那么保持活动将会失败。

因此,当拉线时,我会在10秒内(最多)发送保持活动,然后发生BeginGetResponse的回调。在回调中,当我调用req.EndGetResponse()时,我得到了异常。

我认为这会打败长期民意调查的好处之一。因为我们还在发送数据包。

答案 1 :(得分:3)

我会留给你试试拔掉插头。

ManualResetEvent done = new ManualResetEvent(false);

void Main()
{        
    // set physical address of network adapter to monitor operational status
    string physicalAddress = "00215A6B4D0F";

    // create web request
    var request = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://stackoverflow.com"));

    // create timer to cancel operation on loss of network
    var timer = new System.Threading.Timer((s) => 
    {
        NetworkInterface networkInterface = 
            NetworkInterface.GetAllNetworkInterfaces()
                .FirstOrDefault(nic => nic.GetPhysicalAddress().ToString() == physicalAddress);

        if(networkInterface == null)
        {
            throw new Exception("Could not find network interface with phisical address " + physicalAddress + ".");
        }
        else if(networkInterface.OperationalStatus != OperationalStatus.Up)
        {
            Console.WriteLine ("Network is down, aborting.");
            request.Abort();
            done.Set();
        }
        else
        {
            Console.WriteLine ("Network is still up.");
        }
    }, null, 100, 100);

    // start asynchronous request
    IAsyncResult asynchResult = request.BeginGetResponse(new AsyncCallback((o) =>
    {
        try
        {           
            var response = (HttpWebResponse)request.EndGetResponse((IAsyncResult)o); 
            var reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
            var writer = new StringWriter();
            writer.Write(reader.ReadToEnd());
            Console.Write(writer.ToString());
        }
        finally
        {
            done.Set();
        }
    }), null);

    // wait for the end
    done.WaitOne();
}

答案 2 :(得分:2)

我不认为你会喜欢这个。在向慢速服务器创建请求后,您可以测试Internet连接。

有很多方法可以做到这一点 - 从另一个请求到google.com(或网络中的某些IP地址)到P / Invoke。您可以在此处获取更多信息:Fastest way to test internet connection

创建原始请求后,您将进入一个检查互联网连接的循环,直到互联网关闭或原始请求返回(它可以设置变量来停止循环)。

有帮助吗?

相关问题