wake-up-neo.com

In C # wird überprüft, ob a TCP Port ist verfügbar?

Wie kann ich in C # einen TcpClient verwenden oder allgemein eine Verbindung zu einem Socket herstellen?

Weitere Informationen: .__ Dies ist der Code, den ich verwende:

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

Da Sie eine TcpClient verwenden, überprüfen Sie die offenen TCP - Ports. Im Namespace System.Net.NetworkInformation sind viele gute Objekte verfügbar.

Verwenden Sie das IPGlobalProperties-Objekt, um zu einem Array von TcpConnectionInformation-Objekten zu gelangen, das Sie dann nach Endpunkt-IP und -Port abfragen können.


 int port = 456; //<--- This is your value
 bool isAvailable = true;

 // Evaluate current system tcp connections. This is the same information provided
 // by the netstat command line application, just in .Net strongly-typed object
 // form.  We will look through the list, and if our port we would like to use
 // in our TcpClient is occupied, we will set isAvailable to false.
 IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
 TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();

 foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
 {
   if (tcpi.LocalEndPoint.Port==port)
   {
     isAvailable = false;
     break;
   }
 }

 // At this point, if isAvailable is true, we can proceed accordingly.
202
jro

Sie befinden sich am falschen Ende des Intertube. Es ist der Server, an dem nur ein bestimmter Port geöffnet sein kann. Etwas code:

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

Schlägt fehl mit:

Normalerweise ist nur eine Verwendung jeder Socket-Adresse (Protokoll/Netzwerkadresse/Port) zulässig.

39
Hans Passant

Wenn Sie eine TCP -Verbindung einrichten, muss der 4-Tuple (Quell-IP, Quell-Port, Ziel-IP, Ziel-Port) eindeutig sein. Dadurch wird sichergestellt, dass Pakete an die richtige Stelle gesendet werden.

Auf der Seite Server gibt es eine weitere Einschränkung, dass nur ein Serverprogramm an eine eingehende Portnummer gebunden werden kann (unter der Annahme einer IP-Adresse; Multi-NIC-Server haben andere Fähigkeiten, aber wir müssen sie hier nicht diskutieren ).

Also auf der Serverseite:

  • erstellen Sie eine Steckdose.
  • binden Sie diesen Socket an einen Port.
  • hör auf diesen Hafen.
  • akzeptieren Sie Verbindungen an diesem Port . und es können mehrere Verbindungen eingehen (eine pro Client).

Auf der Clientseite ist es normalerweise etwas einfacher:

  • erstellen Sie eine Steckdose.
  • Öffnen Sie die Verbindung ..__ Wenn ein Client die Verbindung öffnet, gibt er die IP-Adresse und den Port des Server an. Can gibt den Quellport an, verwendet jedoch normalerweise Null, wodurch das System automatisch einen freien Port zuweist.

Es ist no Voraussetzung, dass die Ziel-IP/der Zielport eindeutig sein muss, da dann jeweils nur eine Person Google verwenden kann und das Geschäftsmodell dadurch völlig zerstört wird.

Dies bedeutet, dass Sie sogar so wundersame Dinge tun können, wie z. B. das Multi-Session-FTP-Verfahren, da Sie mehrere Sitzungen einrichten, bei denen der einzige Unterschied der Quellport ist, sodass Sie Chunks parallel herunterladen können. Torrents unterscheiden sich insofern, als das Ziel jeder Sitzung normalerweise unterschiedlich ist.

Nach all dem Trübsal (Entschuldigung) lautet die Antwort auf Ihre spezifische Frage, dass Sie keinen freien Port angeben müssen. Wenn Sie eine Verbindung zu einem Server herstellen, bei dem der Quellport nicht angegeben ist, wird fast immer Null unter den Deckblättern verwendet, und das System gibt Ihnen einen ungenutzten.

19
paxdiablo
TcpClient c;

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

Wie kann ich zuerst prüfen, ob ein bestimmter Port auf meinem Computer frei ist?

Ich meine, dass es von keiner anderen Anwendung verwendet wird. Wenn eine Anwendung einen Port verwendet, können andere ihn nicht verwenden, bis er frei wird. - ALi

Sie haben missverstanden, was hier passiert. 

TcpClient (...) -Parameter beziehen sich auf die Server-IP-Adresse und den Server-Port, zu dem Sie eine Verbindung herstellen möchten. 

Der TcpClient wählt einen transienten lokalen Port aus dem verfügbaren Pool aus, um mit dem Server zu kommunizieren. Es muss nicht nach der Verfügbarkeit des lokalen Ports gesucht werden, da er automatisch vom Winsock-Layer verarbeitet wird.

Falls Sie mit dem obigen Codefragment keine Verbindung zum Server herstellen können, kann es sich um ein oder mehrere Probleme handeln. (d. h. Server-IP und/oder -Port ist falsch, Remote-Server nicht verfügbar usw.)

15
Indy9000

Danke für diesen Tipp. Ich brauchte die gleiche Funktionalität, aber auf der Serverseite, um zu überprüfen, ob ein Port verwendet wurde. Daher habe ich ihn an diesen Code angepasst.

 private bool CheckAvailableServerPort(int port) {
    LOG.InfoFormat("Checking Port {0}", port);
    bool isAvailable = true;

    // Evaluate current system tcp connections. This is the same information provided
    // by the netstat command line application, just in .Net strongly-typed object
    // form.  We will look through the list, and if our port we would like to use
    // in our TcpClient is occupied, we will set isAvailable to false.
    IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
    IPEndPoint[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();

    foreach (IPEndPoint endpoint in tcpConnInfoArray) {
        if (endpoint.Port == port) {
            isAvailable = false;
            break;
        }
    }

    LOG.InfoFormat("Port {0} available = {1}", port, isAvailable);

    return isAvailable;
}
14
Melloware
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);
}
6
Learning

danke für die antwort jro. Ich musste es für meinen Gebrauch anpassen. Ich musste überprüfen, ob ein Port abgehört wurde und nicht unbedingt aktiv war. Dafür habe ich ersetzt 

TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();

mit 

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

Ich wiederholte das Array von Endpunkten und überprüfte, ob mein Portwert nicht gefunden wurde.

6
user336046

netstat! Dies ist ein Netzwerk-Befehlszeilen-Dienstprogramm, das mit Windows geliefert wird. Es zeigt alle aktuell eingerichteten Verbindungen und alle Ports, die gerade abgehört werden. Sie können dieses Programm verwenden, um dies zu überprüfen, aber wenn Sie dies vom Code aus tun möchten, schauen Sie in den Namespace System.Net.NetworkInformation. Es ist ein neuer Namespace ab 2.0. Es gibt einige gute Sachen dort. Wenn Sie jedoch die gleichen Informationen erhalten möchten, die über den Befehl netstat verfügbar sind, müssen Sie P/Invoke ausführen.

Update: System.Net.NetworkInformation

Dieser Namespace enthält eine Reihe von Klassen, die Sie verwenden können, um Dinge über das Netzwerk herauszufinden.

Ich konnte dieses alte Stück Code nicht finden, aber ich denke, dass Sie selbst etwas ähnliches schreiben können. Ein guter Anfang ist das Auschecken der IP Helper API . Google MSDN für die GetTcpTable WINAPI-Funktion, und verwenden Sie P/Invoke zum Auflisten, bis Sie über die erforderlichen Informationen verfügen.

3
John Leidegren

ipGlobalProperties.GetActiveTcpConnections() gibt keine Verbindungen im Listen-Status zurück.

Port kann für das Abhören verwendet werden, aber wenn keine Verbindung besteht, funktioniert die oben beschriebene Methode nicht.

2
Broken Pipe

Wenn ich mich nicht sehr irre, können Sie System.Network.wetwas verwenden, um es zu überprüfen.

Dies führt jedoch immer zu einer Rennbedingung.

Die kanonische Art der Überprüfung besteht darin, diesen Port zu überwachen. Wenn Sie eine Fehlermeldung erhalten, war der Port nicht geöffnet.

Ich denke Dies ist ein Teil des Grunds, warum bind () und listen () zwei getrennte Systemaufrufe sind.

2
Joshua

Du sagst 

Ich meine, es wird von keinem .__ verwendet. andere Anwendung. Wenn eine Bewerbung verwendet einen Port, den andere nicht verwenden können bis es frei wird.

Sie können jedoch immer eine Verbindung zu einem Port herstellen, während andere ihn verwenden, wenn dort etwas zu hören ist. Ansonsten wäre der HTTP-Port 80 ein Durcheinander.

Wenn dein 

   c = new TcpClient(ip, port);

scheitert, dann hört nichts dort zu. Andernfalls wird eine Verbindung hergestellt, auch wenn auf einer anderen Maschine/Anwendung ein Socket für diese IP-Adresse und diesen Port vorhanden ist.

2
Moose
    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;
    }
1

Seien Sie sich bewusst, dass das Zeitfenster zwischen der Überprüfung und dem Moment, in dem Sie versuchen, eine Verbindung herzustellen, einige Zeit in Anspruch nehmen kann - klassisch TOCTOU . Warum versuchst du nicht einfach, eine Verbindung herzustellen? Wenn dies fehlschlägt, wissen Sie, dass der Port nicht verfügbar ist.

1
ya23

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

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

Mit folgendem Import:

using System.Net.NetworkInformation;

Mit der folgenden Funktion können Sie prüfen, ob ein Port 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 verwenden:

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
1
Simone

Sie müssen nicht wissen, welche Ports auf Ihrem lokalen Computer geöffnet sind, um eine Verbindung zu einem entfernten TCP - Dienst herzustellen (es sei denn, Sie möchten einen bestimmten lokalen Port verwenden, dies ist jedoch normalerweise nicht der Fall).

Jede TCP/IP-Verbindung wird durch 4 Werte identifiziert: Remote-IP, Remote-Portnummer, lokale IP-Adresse, lokale Portnummer. Sie müssen jedoch nur Remote-IP und Remote-Portnummer kennen, um eine Verbindung herzustellen. 

Beim Erstellen einer TCP-Verbindung mit

 TcpClient c; 
 C = neuer TcpClient (remote_ip, remote_port); 

Ihr System weist Ihrer Verbindung automatisch eine von vielen freien lokalen Portnummern zu. Sie müssen nichts tun ... Sie möchten vielleicht auch prüfen, ob ein Remote-Port geöffnet ist. Aber es gibt keinen besseren Weg, als nur zu versuchen, eine Verbindung herzustellen.

1
test_connection("ip", port);


public void test_connection(String hostname, int portno) {
  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) {
     MessageBox.Show("Port is in use");
   }

   sock.Close();
 }
 catch (System.Net.Sockets.SocketException ex) {
   if (ex.ErrorCode == 10060) {
     MessageBox.Show("No connection.");
   }
 }
}
0
Yuriy Stanchev

Überprüfen Sie den Fehlercode 10048

try
{
    TcpListener tcpListener = new TcpListener(ipAddress, portNumber);
    tcpListener.Start();
}
catch(SocketException ex)
{
    if(ex.ErrorCode == 10048)
    {
        MessageBox.Show("Port " + portNumber + " is currently in use.");
    }
    return;
}
0
Mohsen