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


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);



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助手API 。 Google MSDN的GetTcpTable WINAPI函數,並使用P / Invoke枚舉,直到你有你需要的信息。




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

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

規範的檢查方法是嘗試在該端口上收聽。 如果你得到一個錯誤,端口沒有打開。

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




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




    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;
    }



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

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