應用程式使用 .NET WebClient 類別執行偵測新版本以及線上自動更新的功能,可是如果伺服器因為某些原因無法連線(如網路斷線、伺服器關機等),應用程式在檢查是否有更新版時,就得等 20 秒左右才會發生連線失敗。
想要使用 Socket 或 TcpClient 類別事先偵測伺服器的 80 port 能否連線,可是結果還是一樣,因為它們並沒有提供連線逾時的屬性。
解決方法
可使用非同步的方式解決。以下是利用 TcpClient 類別偵測伺服器 80 port 能否連接的工具函式:
/// <summary>
/// 偵測指定的伺服器的特定 port 是否可以連接。
/// </summary>
/// <param name="host">伺服器名稱或 IP 位址。</param>
/// <param name="port">Port 號。</param>
/// <param name="timeOut">連線逾時時間,單位:秒。</param>
/// <returns></returns>
private bool IsServerConnectable(string host, int port, double timeOut)
{
TcpClient tcp = new TcpClient();
DateTime t = DateTime.Now;
try
{
IAsyncResult ar = tcp.BeginConnect(host, port, null, null);
while (!ar.IsCompleted)
{
if (DateTime.Now > t.AddSeconds(timeOut))
{
throw new Exception("Connection timeout!");
}
System.Threading.Thread.Sleep(100);
}
tcp.EndConnect(ar);
tcp.Close();
return true;
}
catch
{
return false;
}
}
呼叫 IsServerConnectable 時,可將參數 timeOutSeconds 指定為 1,如此一來,函式最多只等待 1 秒便會立即傳回結果。
2008-11-22 增加:偵測某個網頁是否能正常回應
private void PingWebPage(string url, int timeout)
{
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
req.Method = "GET";
req.Credentials = CredentialCache.DefaultCredentials;
req.ContentType = "text/xml";
req.Timeout = timeout;
WebResponse rsp = req.GetResponse();
StreamReader sr = new StreamReader(rsp.GetResponseStream(), Encoding.UTF8);
try
{
sr.ReadLine();
}
finally
{
sr.Close();
rsp.Close();
}
}
p.s. 以上程式碼是由 CopySourceAsHtml 產生。選項:Wrap words + Embed styles + Overwrite tab size + Overwrite font list (Fixedsys) + Strip line breaks。
沒有留言: