[C#] 在C#中,如何檢查TCP端口是否可用?



Answers

你在Intertube的錯誤端。 它是只能打開一個特定端口的服務器。 一些代碼:

  IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
  try {
    TcpListener tcpListener = new TcpListener(ipAddress, 666);
    tcpListener.Start();
  }
  catch (SocketException ex) {
    MessageBox.Show(ex.Message, "kaboom");
  }

失敗:

通常只允許使用每個套接字地址(協議/網絡地址/端口)。

Question

在C#中使用TcpClient或通常連接到套接字如何首先檢查我的機器上某個端口是否可用?

更多信息:這是我使用的代碼:

TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);



嘗試這個,在我的情況下,創建的對象的端口號不可用,所以我想出了這個

IPEndPoint endPoint;
int port = 1;
while (true)
{
    try
    {
        endPoint = new IPEndPoint(IPAddress.Any, port);
        break;
    }
    catch (SocketException)
    {
         port++;
    }
}



如果我沒有弄錯,你可以使用System.Network.whatever來檢查。

但是,這總是會導致競爭狀況。

規範的檢查方式是嘗試在該端口上收聽。 如果您收到一個錯誤,說明該端口未打開。

認為這是為什麼bind()和listen()是兩個獨立的系統調用的一部分。




    public static bool TestOpenPort(int Port)
    {
        var tcpListener = default(TcpListener);

        try
        {
            var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];

            tcpListener = new TcpListener(ipAddress, Port);
            tcpListener.Start();

            return true;
        }
        catch (SocketException)
        {
        }
        finally
        {
            if (tcpListener != null)
                tcpListener.Stop();
        }

        return false;
    }



TcpClient c;

//I want to check here if port is free.
c = new TcpClient(ip, port);

...我如何首先檢查我的機器上的某個端口是否可用?

我的意思是它沒有被任何其他應用程序使用。 如果應用程序使用端口,則其他人無法使用它,直到它變為空閒為止。 - 阿里

你誤解了這裡發生的事情。

TcpClient(...)參數是您希望連接到的服務器IP和服務器端口的參數。

TcpClient從可用池中選擇一個臨時本地端口與服務器進行通信。 沒有必要檢查本地端口的可用性,因為它由winsock層自動處理。

如果您無法使用上述代碼片段連接到服務器,則問題可能是一個或多個。 (即服務器IP和/或端口是錯誤的,遠程服務器不可用,等等。)




string hostname = "localhost";
int portno = 9081;
IPAddress ipa = (IPAddress) Dns.GetHostAddresses(hostname)[0];


try
{
    System.Net.Sockets.Socket sock = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
    sock.Connect(ipa, portno);
    if (sock.Connected == true)  // Port is in use and connection is successful
            MessageBox.Show("Port is Closed");
    sock.Close();

}
catch (System.Net.Sockets.SocketException ex)
{
    if (ex.ErrorCode == 10061)  // Port is unused and could not establish connection 
        MessageBox.Show("Port is Open!");
    else
        MessageBox.Show(ex.Message);
}



netstat的! 這是一個與Windows一起發布的網絡命令行工具。 它顯示所有當前建立的連接和當前正在監聽的所有端口。 你可以使用這個程序來檢查,但是如果你想從代碼中查看System.Net.NetworkInformation命名空間呢? 這是一個2.0的新命名空間。 那裡有些好東西。 但最終如果你想獲得通過命令netstat獲得的相同類型的信息,則需要導致P / Invoke ...

更新:System.Net.NetworkInformation

該命名空間包含一系列可用於計算網絡事件的類。

我無法找到那些舊代碼,但我認為你可以自己寫一些類似的東西。 一個好的開始是檢查IP Helper API 。 用於GetTcpTable WINAPI函數的Google MSDN,並使用P / Invoke進行枚舉,直到獲得所需的信息。




請注意您進行檢查的時間窗口以及您嘗試進行連接的時間,某些過程可能需要端口 - 古典TOCTOU 。 你為什麼不嘗試連接? 如果失敗,那麼您知道該端口不可用。




Links