148 Stimmen

Wie kann man in C# prüfen, ob ein TCP-Port verfügbar ist?

In C# zu verwenden, ein TcpClient oder im Allgemeinen zu einem Socket zu verbinden, wie kann ich zuerst überprüfen, ob ein bestimmter Port auf meinem Rechner frei ist?

Mehr Informationen: Dies ist der von mir verwendete Code:

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

8voto

CCondron Punkte 1796

Um die genaue Frage nach einem freien Port (den ich für meine Unit-Tests benötigte) in Dotnet Core 3.1 zu beantworten, kam ich auf Folgendes

public static int GetAvailablePort(IPAddress ip) {
        TcpListener l = new TcpListener(ip, 0);
        l.Start();
        int port = ((IPEndPoint)l.LocalEndpoint).Port;
        l.Stop();
        Log.Info($"Available port found: {port}");
        return port;
    }

Anmerkung: Aufgrund des Kommentars von @user207421 über Port Zero habe ich gesucht und gefunden este und leicht verändert.

7voto

Simone Punkte 1187

Von den verfügbaren Häfen würde ich ausschließen:

  • aktive TCP-Verbindungen
  • aktive TCP-Listener
  • aktive UDP-Listener

Mit dem folgenden Import:

using System.Net.NetworkInformation;

Sie können die folgende Funktion verwenden, um zu prüfen, ob ein Anschluss verfügbar ist oder nicht:

private bool isPortAvalaible(int myPort)
{
    var avalaiblePorts = new List<int>();
    var properties = IPGlobalProperties.GetIPGlobalProperties();

    // Active connections
    var connections = properties.GetActiveTcpConnections();
    avalaiblePorts.AddRange(connections);

    // Active tcp listners
    var endPointsTcp = properties.GetActiveTcpListeners();
    avalaiblePorts.AddRange(endPointsTcp);

    // Active udp listeners
    var endPointsUdp = properties.GetActiveUdpListeners();
    avalaiblePorts.AddRange(endPointsUdp);

    foreach (int p in avalaiblePorts){
        if (p == myPort) return false;
    }
    return true;
}

Ich gebe Ihnen eine ähnliche Funktion für diejenigen, die VB.NET :

Imports System.Net.NetworkInformation
Private Function isPortAvalaible(ByVal myPort As Integer) As Boolean
  Dim props As IPGlobalProperties = IPGlobalProperties.GetIPGlobalProperties()

  ' ignore active connections
  Dim tcpConnInfoArray() As TcpConnectionInformation = props.GetActiveTcpConnections()
  For Each tcpi As Net.NetworkInformation.TcpConnectionInformation In tcpConnInfoArray
    If tcpi.LocalEndPoint.Port = myPort Then
      Return False
    End If
  Next tcpi

  ' ignore active TCP listeners
  Dim activeTcpListeners() As Net.IPEndPoint = props.GetActiveTcpListeners
  For Each tcpListener As Net.IPEndPoint In activeTcpListeners
    If tcpListener.Port = myPort Then
      Return False
    End If
  Next tcpListener

  ' ignore active UPD listeners
  Dim activeUdpListeners() As Net.IPEndPoint = props.GetActiveUdpListeners
  For Each udpListener As Net.IPEndPoint In activeUdpListeners
    If udpListener.Port = myPort Then
      Return False
    End If
  Next udpListener

  Return True
End Function

7voto

user336046 Punkte 69

Danke für die Antwort jro. Ich musste es für meine Zwecke anpassen. Ich musste prüfen, ob ein Port abgehört wird, der nicht unbedingt aktiv ist. Dafür habe ich ersetzt

TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();

con

IPEndPoint[] objEndPoints = ipGlobalProperties.GetActiveTcpListeners();.  

Ich habe das Array der Endpunkte durchlaufen und überprüft, dass mein Port-Wert nicht gefunden wurde.

5voto

Learning Punkte 7731
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);
}

3voto

Joshua Punkte 37898

Wenn ich mich nicht sehr irre, können Sie System.Network.whatever zur Überprüfung verwenden.

Dies führt jedoch immer zu einer Race Condition.

Der klassische Weg der Überprüfung besteht darin, zu versuchen, auf diesem Port zu lauschen. Wenn Sie eine Fehlermeldung erhalten, war der Port nicht offen.

I pensez à Dies ist einer der Gründe, warum bind() und listen() zwei separate Systemaufrufe sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X