2013-08-27 108 views
2

我試圖建立一個到特定端口的主機/ IP地址的套接字連接。主要的事情,我儘量做到有:c#套接字檢查連接

  • 得到以毫秒爲單位的展位成功的響應時間/失敗連接
  • 使用自定義超時例如,5秒(5000)

所以基本上如果我指定一個主機名如google.com和端口80這應該檢查連接是否有效,如果我指定173.194.70.101和端口80它應該工作。

如果我指定例如主機名稱,如google.com和端口7788這應該不起作用,因爲該端口未打開。如果我指定IP:173.194.70.101和端口'7788',這應該不起作用。

如果我指定一些隨機主機,如sdfzsdfaklsf.com和端口7788,這應該不起作用,因爲主機不存在。

對於所有的情況下,以上我所需要的響應時間爲所有的成功/失敗...

我結束了這段代碼和接縫做工精細,但是我想問一下,如果這是一個正確的方法做到這一點?

 public string CheckConnection(string ipAddressOrHostName, string portName) 
    { 
     Stopwatch timer = new Stopwatch(); 
     timer.Start(); 
     Socket server = null; 
     string elapsed = string.Empty; 

     try 
     { 

      IPHostEntry hostEntry = Dns.GetHostEntry(ipAddressOrHostName); 

      IPAddress ipAddress = hostEntry.AddressList[0]; 

      IPEndPoint ip = new IPEndPoint(ipAddress, Convert.ToInt32(portName)); 

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

      IAsyncResult result = server.BeginConnect(ip, null, null); 

      result.AsyncWaitHandle.WaitOne(5000, true); 

      timer.Stop(); 

      elapsed = timer.ElapsedMilliseconds.ToString(); 


      if (!server.Connected) 
      {      
       server.Close(); 
       throw new Exception(); 
      } 
      else 
      { 
       string status = string.Format("Connected succesfully to: {0} in: {1} milliseconds", server.RemoteEndPoint.ToString(), elapsed);     
       server.Shutdown(SocketShutdown.Both); 
       server.Close(); 

       return status; 
      } 
     } 
     catch (Exception) 
     { 
      timer.Stop(); 

      elapsed = timer.ElapsedMilliseconds.ToString(); 

      return string.Format("Connection failed to: {0}:{1} in: {2} milliseconds", ipAddressOrHostName, portName, elapsed);      
     } 

    } 
+0

我會改善你的異常處理。不推薦捕獲一般異常並將其視爲特定網絡/連接失敗。也可以嘗試把你的close/shutdown/stop調用放到'finally'塊中....除此之外,我認爲這看起來很好.. –

回答

2

這很不錯。幾點:

  1. 捕獲更多特定類型的異常並測試它。你不想捕捉不相關的東西或隱藏錯誤。
  2. 啓動計時器您已完成DNS解析。
  3. throw new Exception不太好,因爲例外情況不意味着控制流程。重構方法不需要這個破解。
  4. 您可能需要使用任務而不是IAsyncResult。沒有功能變化,只是更現代的風格。
  5. 您在幾個地方有冗餘(例如重複的關閉,重複的ToString)。
  6. 解析方法以外的端口。它不屬於那裏。事實上,如果端口不可分析,那麼此時將觸發一個可察覺的超時,因爲會拋出異常。這是我在第(1)點警告你的。過多地使用異常導致了一個你可能永遠不會知道的bug,因爲它是隱藏的。
+0

你能告訴我怎樣才能實現異步等待而不是IAsyncResult? –

+0

我認爲這超出了這個問題的範圍。搜索「等待插座」找到答案。如果您還有其他問題,請告訴我。 – usr

+0

我確實實現了異步等待而不是IAsyncResult,但是我放鬆了自定義超時的控制,默認情況下是20秒,我認爲......但無論如何感謝您的意見! –