146 votes

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

En C#, pour utiliser un TcpClient ou plus 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'informations : Voici le code que j'utilise :

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

4 votes

Qu'entendez-vous par "gratuit" ici ? Si vous essayez de vous y connecter et que vous échouez, cela signifie probablement que rien n'a été écouté.

2 votes

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

0 votes

Quel est le serveur auquel vous essayez de vous connecter ? L'avez-vous écrit ou s'agit-il d'un serveur existant ?

253voto

jro Points 5120

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

Utilisez le IPGlobalProperties pour accéder à un tableau de TcpConnectionInformation que vous pouvez ensuite interroger sur l'IP et le port du terminal.


 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.

44 votes

N'oubliez pas qu'un autre processus peut se lier à ce port pendant que vous vérifiez.

0 votes

Bon point, très possible. Pas sûr que l'on puisse verrouiller ou mutexer l'accès exclusif à un port.

3 votes

En quoi cela est-il pertinent pour la question ? Cette réponse traite de local ports, et non à distance ports.

52voto

Hans Passant Points 475940

Vous êtes du mauvais côté de l'Intertube. C'est le serveur qui ne peut avoir qu'un seul port particulier ouvert. Un peu de 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");
  }

Échoue avec :

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

0 votes

C'est là où je voulais en venir aussi. Quelqu'un est définitivement confus ici, et c'est possible que ce soit moi.

3 votes

Il est possible que le client exige également un certain port, mais ce n'est pas courant.

0 votes

@DaveVandenEynde cela ne peut se produire que si le "client" est en train de "servir" quelque chose sur ce port particulier (ce qui en fait un "serveur", au moins pour ce port, dans la mesure où TCP est concerné). -- Lorsque vous avez une connexion TCP client, vous n'avez pas le contrôle du port de sortie. La pile TCP vous assigne un port de sortie, et vous n'avez aucun contrôle sur celui-ci.

19voto

paxdiablo Points 341644

Lorsque vous établissez une connexion TCP, le quadruplet (source-ip, source-port, dest-ip, dest-port) doit être unique, afin de garantir la livraison des paquets au bon endroit.

Il existe une autre restriction sur le serveur Il est à noter 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, du côté du serveur, vous :

  • créer un socket.
  • lier cette socket à un port.
  • écouter sur ce port.
  • accepter des connexions sur ce port. et il peut y avoir plusieurs connexions entrantes (une par client).

Du côté du client, c'est généralement un peu plus simple :

  • créer un socket.
  • ouvrir la connexion. Lorsqu'un client ouvre la connexion, il spécifie l'adresse IP et le port de l'ordinateur. serveur . Il s'agit de puede spécifier son port source mais utilise généralement zéro, ce qui fait que le système lui attribue automatiquement un port libre.

Il y a pas de l'exigence que l'IP/le port de destination soit unique, car cela aurait pour conséquence qu'une seule personne à la fois pourrait utiliser Google, ce qui détruirait pratiquement leur modèle économique.

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, ce qui vous permet de télécharger des morceaux en parallèle. Les torrents sont un peu différents dans la mesure où la destination de chaque session est généralement différente.

Après toutes ces explications, 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 est presque certain qu'il utilisera un port zéro et le système vous donnera un port inutilisé.

17voto

Melloware Points 819

Merci pour ce conseil. J'avais besoin de la même fonctionnalité mais du côté du serveur pour vérifier si un port était utilisé. J'ai donc modifié 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;
}

0 votes

Vous n'avez pas besoin de ça. Il suffit de spécifier le port zéro.

1 votes

La note dans le commentaire du code source : "Il s'agit des mêmes informations fournies par l'application de ligne de commande netstat" -- est un mensonge. Elle ne fournit pas les mêmes informations car la commande netstat fournit également le PID de l'application utilisant le port ( -anb ) et sans aucun paramètre il montre la connexion étrangère ainsi que l'état.

16voto

Kip9000 Points 4462
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 pas utilisé par une autre application. Si une application utilise un port, les autres ne peuvent pas l'utiliser jusqu'à ce qu'il devienne libre. - Ali

Vous avez mal compris ce qui se passe ici.

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

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

Si vous ne parvenez pas à vous connecter au serveur à l'aide du fragment de code ci-dessus, le problème peut provenir d'un ou plusieurs des éléments suivants. (i.e. l'ip et/ou le port du serveur est incorrect, le serveur distant n'est pas disponible, etc )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X