2016-01-06 31 views
2

我想測試服務器是否活着給定IPEndpoint。我嘗試了以下方法,但它有時會返回錯誤的結果。使用c測試與服務器的連接#

public bool IsAlive(IPEndPoint ipEndPoint) 
{ 
    if (ipEndPoint == null) return false; 

    var tcpClient = new TcpClient(); 
    var bConnect = tcpClient.BeginConnect(ipEndPoint.Address, ipEndPoint.Port, null, null); 
    var isAlive = bConnect.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(1000)); 
    return isAlive; 
} 

這種方法有什麼問題?

+2

請你可以擴展你的意思是「它有時會返回錯誤的結果」? – ChrisF

+0

當然,我正在用下面的代碼測試這個方法。 (true) { Console.WriteLine(IsAlive(new IPEndPoint(IPAddress.Parse(「127.0.0.1」),1234))。ToString()); Console.ReadKey(); } ' – tchelidze

+0

它有時打印真實,有時是錯誤的。 – tchelidze

回答

1

只是因爲AsyncWaitHandle完成不會超時,並不意味着它連接成功。你需要調用tcpClient.EndConnect(,看看它是否拋出異常,如果沒有拋出異常,那麼所有的都是好的,如果不是連接是壞的。另外,如果您的連接成功,則在原始方法中不關閉連接。

如果您使用.NET 4.5或更新版本,則易於實現,請使用ConnectAsync而不是開始/結束對,然後您可以使用await

public async Task<bool> IsAliveAsync(IPEndPoint ipEndPoint) 
{ 
    if (ipEndPoint == null) return false; 

    using(var tcpClient = new TcpClient()) 
    { 
    var connectTask = tcpClient.ConnectAsync(ipEndPoint.Address, ipEndPoint.Port) 
    var timeoutTask = Task.Delay(1000); 
    var finishedTask = await Task.WhenAny(connectTask, timeoutTask).ConfigureAwait(false); 

    bool isAlive; 
    if(finishedTask == timeoutTask) 
    { 
     isAlive = false; 
    } 
    else 
    { 
     try 
     { 
      await connectTask.ConfigureAwait(false); 
      isAlive = true; 
     } 
     catch 
     { 
     isAlive = false; 
     } 
    } 

    return isAlive; 
    } 
} 

,因爲我使用.ConfigureAwait(false)我到處await應該是安全地調用.Result的任務此方法而不是做異步/ AWAIT一路上揚調用棧返回。