En C#, Comment vérifier si un port TCP est disponible?

En C# pour utiliser un TcpClient ou généralement pour se connecter à un socket Comment puis-je d'abord vérifier si un certain port est libre sur ma machine?

plus d'infos: C'est le code que j'utilise:

TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
108
demandé sur Ali 2009-02-20 18:53:37

17 réponses

Puisque vous utilisez un TcpClient, cela signifie que vous vérifiez les ports TCP ouverts. Il y a beaucoup de bons objets disponibles dans l'espace de noms System.Net.NetworkInformation.

Utilisez l'objet IPGlobalProperties pour accéder à un tableau d'objets TcpConnectionInformation, que vous pouvez ensuite interroger sur l'adresse IP et le port du point de terminaison.


 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.
200
répondu jro 2013-01-07 10:59:38

Vous êtes sur le mauvais bout de L'Intertube. C'est le serveur qui ne peut avoir qu'un seul port particulier ouvert. Certains codes:

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

Échoue avec:

Une Seule utilisation de chaque adresse de socket (protocole/adresse réseau/port) est habituellement autorisée.

39
répondu Hans Passant 2015-04-02 06:47:13

Lorsque vous configurez une connexion TCP, le 4-tuple (source-ip, source-port, dest-ip, dest-port) doit être unique - c'est pour s'assurer que les paquets sont livrés au bon endroit.

Il y a une autre restriction sur le côté Serveur qu'un seul programme serveur peut se lier à un numéro de port entrant (en supposant une adresse IP; les serveurs multi-NIC ont d'autres pouvoirs mais nous n'avons pas besoin d'en discuter ici).

Donc, à la fin du serveur, vous:

  • créer un socket.
  • lie ce socket à un port.
  • écoutez sur ce port.
  • accepte les connexions sur ce port. et il peut y avoir plusieurs connexions à venir (une par client).

À la fin du client, c'est généralement un peu plus simple:

  • créer un socket.
  • ouvrez la connexion. Lorsqu'un client ouvre la connexion, il spécifie l'adresse ip et le port du serveur . Il Peut spécifier son port source mais utilise généralement zéro qui résulte dans le système lui attribuant un port libre automatiquement.

Il n'y a aucune exigence que L'adresse IP/port de destination soit unique, car cela permettrait à une seule personne à la fois d'utiliser Google, ce qui détruirait assez bien leur modèle commercial.

Cela signifie que vous pouvez même faire des choses merveilleuses comme le FTP multi-session puisque vous configurez plusieurs sessions où la seule différence est votre port source, vous permettant de télécharger des morceaux en parallèle. Torrent sont un peu différents en ce sens que la destination de chaque session est généralement différente.

Et, après tout ce gaufrage (désolé), la réponse à votre question spécifique est que vous n'avez pas besoin de spécifier un port libre. Si vous vous connectez à un serveur avec un appel qui ne spécifie pas votre port source, il utilisera presque certainement zéro sous les couvertures et le système vous en donnera un inutilisé.

19
répondu paxdiablo 2009-04-07 02:59:05
TcpClient c;

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

...Comment puis-je d'abord vérifier si un certain port est libre sur ma machine?

Je veux dire qu'il n'est utilisé par aucune autre application. Si une application utilise un port, d'autres ne peuvent pas l'utiliser jusqu'à ce qu'il devienne libre. - Ali

Vous avez mal compris ce qui se passe ici.

TcpClient(...) les paramètres sont de l'ip du serveur et du port du serveur auquel vous souhaitez vous connecter.

Le TcpClient sélectionne un port local transitoire dans le pool disponible pour communiquer pour le serveur. Il n'est pas nécessaire de vérifier la disponibilité du port local car il est automatiquement géré par la couche winsock.

Dans le cas où vous ne pouvez pas vous connecter au serveur en utilisant le fragment de code ci-dessus, le problème pourrait être un ou plusieurs de plusieurs. (c'est-à-dire que l'ip et/ou le port du serveur sont incorrects, que le serveur distant n'est pas disponible, etc..)

14
répondu Indy9000 2009-04-03 08:48:28

Merci pour ce conseil. J'avais besoin de la même fonctionnalité mais du côté serveur pour vérifier si un Port était utilisé, donc je l'ai modifié pour ce code.

 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;
}
13
répondu Melloware 2010-11-12 13:59:19
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
répondu Learning 2009-02-20 16:02:32

Merci pour la réponse jro. J'ai dû le modifier pour mon utilisation. J'avais besoin de vérifier si un port était écouté, et pas neccessarily actif. Pour cela, j'ai remplacé

TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();

Avec

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

J'ai itéré le tableau de points de terminaison en vérifiant que ma valeur de port n'a pas été trouvée.

6
répondu user336046 2010-10-14 19:49:31

Netstat! C'est un utilitaire de ligne de commande réseau qui est livré avec windows. Il montre toutes les connexions établies actuelles et tous les ports actuellement écoutés. Vous pouvez utiliser ce programme pour vérifier, mais si vous voulez le faire à partir du code, regardez dans L'espace de noms System.Net.NetworkInformation? C'est un nouvel espace de noms à partir de 2.0. Il y a des friandises là-bas. Mais finalement si vous voulez obtenir le même genre d'informations qui est disponible via la commande netstat vous devrez résultat à P / Invoke...

Mise À Jour: System. Net. NetworkInformation

Cet espace de noms contient un tas de classes que vous pouvez utiliser pour trouver des choses sur le réseau.

Je n'ai pas pu trouver ce vieux pice de code mais je pense que vous pouvez écrire quelque chose de similaire vous-même. Un bon début est de vérifier l'API IP Helper . Google MSDN pour la fonctionGETTCPTABLE WINAPI et utilisez P / Invoke pour énumérer jusqu'à ce que vous ayez les informations dont vous avez besoin.

3
répondu John Leidegren 2009-02-21 12:22:29

Vous dites

Je veux dire qu'il n'est pas utilisé par tout autre application. Si une application utilise un port d'autres ne peuvent pas l'utiliser jusqu'à ce qu'il devient libre.

Mais vous pouvez toujours vous connecter à un port pendant que d'autres l'utilisent si quelque chose est à l'écoute. Sinon, le port http 80 serait un gâchis.

Si votre

   c = new TcpClient(ip, port);

Échoue, alors rien n'écoute là-bas. Sinon, il se connectera, même si une autre machine / application a une prise ouverte à cela adresse ip et le port.

2
répondu Moose 2009-02-20 16:34:30

Si Je ne me trompe pas beaucoup, vous pouvez utiliser System.Réseau.que ce soit pour vérifier.

Cependant, cela entraînera toujours une condition de concurrence.

La façon canonique de vérifier est d'essayer d'écouter sur ce port. Si vous obtenez une erreur, ce port n'était pas ouvert.

Jepense que Cela fait partie de la raison pour laquelle bind() et listen() sont deux appels système distincts.

2
répondu Joshua 2009-04-09 18:20:51

ipGlobalProperties.GetActiveTcpConnections() ne renvoie pas les connexions dans L'État D'écoute.

Port peut être utilisé pour l'écoute, mais sans personne connecté à elle la méthode décrite ci-dessus ne fonctionnera pas.

2
répondu Tevo D 2013-09-27 17:09:08

Soyez conscient de la fenêtre de temps entre vous faites vérifier et le moment où vous essayez de faire la connexion un processus peut prendre le port-classique TOCTOU . Pourquoi ne pas essayer de vous connecter? Si cela échoue, vous savez que le port n'est pas disponible.

1
répondu ya23 2009-04-09 11:35:20

Vous n'avez pas besoin de savoir quels ports sont ouverts sur votre machine locale pour vous connecter à un service TCP distant (sauf si vous souhaitez utiliser un port local spécifique, mais ce n'est généralement pas le cas).

Chaque connexion TCP / IP est identifiée par 4 valeurs: adresse IP distante, numéro de port distant, adresse IP locale, numéro de port local, mais il vous suffit de connaître l'adresse IP distante et le numéro de port distant pour établir une connexion.

Lorsque vous créez une connexion tcp à l'aide de

TcpClient c;
c = new TcpClient(remote_ip, remote_port);

Votre système sera automatiquement attribuez l'un des nombreux numéros de port locaux gratuits à votre connexion. Vous n'avez pas besoin de faire quoi que ce soit. Vous pouvez également vérifier si un port distant est ouvert. mais il n'y a pas de meilleure façon de le faire que de simplement essayer de s'y connecter.

1
répondu Michał Piaskowski 2009-04-09 17:48:15
    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
répondu Martin.Martinsson 2015-04-17 08:14:48
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
répondu Yuriy Stanchev 2016-01-08 15:14:28

Des ports disponibles, j'exclurais:

  • connexions TCP actives
  • écouteurs TCP actifs
  • écouteurs UDP actifs

, Avec l'importation suivante:

using System.Net.NetworkInformation;

Vous pouvez utiliser la fonction suivante pour vérifier si un port est disponible ou non:

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

, je vous donne une fonction similaire pour ceux qui utilisent 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
0
répondu Simone 2018-07-10 10:13:09

Essayez ceci, dans mon cas le numéro de port de l'objet créé n'était pas disponible, donc je suis venu avec ceci

IPEndPoint endPoint;
int port = 1;
while (true)
{
    try
    {
        endPoint = new IPEndPoint(IPAddress.Any, port);
        break;
    }
    catch (SocketException)
    {
         port++;
    }
}
-1
répondu shakram02 2016-05-06 19:52:07