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

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

Utilisez l’object IPGlobalProperties pour accéder à un tableau d’objects TcpConnectionInformation , que vous pouvez ensuite interroger sur l’adresse IP et le port du noeud final.


  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. 

Vous êtes du mauvais côté de l’Intertube. C’est le serveur qui ne peut ouvrir qu’un seul port. Un 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.

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

Il existe une autre ressortingction du côté du serveur : 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
  • lier cette socket à un port.
  • écoutez sur ce port.
  • accepter les connexions sur ce port. et il peut y avoir plusieurs connexions entrant (une par client).

Pour le 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 du serveur . Il peut spécifier son port source mais utilise généralement zéro, ce qui fait que le système lui atsortingbue automatiquement un port libre.

Il n’est pas nécessaire que l’IP / port de destination soit unique car cela ne permettrait à une seule personne à la fois d’utiliser Google, ce qui détruirait bien son modèle commercial.

Cela signifie que vous pouvez même faire des choses aussi merveilleuses que le FTP multi-sessions puisque vous avez configuré 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, car la destination de chaque session est généralement différente.

Et, après tout cela (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 certainement zéro sous les couvertures et le système vous en donnera un inutilisé.

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

… comment puis-je 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, les autres utilisateurs ne peuvent pas l’utiliser jusqu’à ce qu’elle devienne libre. – Ali

Vous avez mal compris ce qui se passe ici.

Les parameters TcpClient (…) sont ceux du serveur IP et du port du serveur auquel vous souhaitez vous connecter.

TcpClient sélectionne un port local transitoire du pool disponible pour communiquer avec 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.

Si vous ne pouvez pas vous connecter au serveur en utilisant le fragment de code ci-dessus, le problème peut être un ou plusieurs de plusieurs. (c.-à-d. le serveur IP et / ou le port est incorrect, le serveur distant n’est pas disponible, etc.)

Merci pour cette astuce. J’avais besoin des mêmes fonctionnalités mais du côté du serveur pour vérifier si un port était utilisé, je l’ai donc 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; } 
 ssortingng 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); } 

merci pour la réponse jro. J’ai dû le modifier pour mon usage. Je devais vérifier si un port était écouté et pas nécessairement actif. Pour cela j’ai remplacé

 TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections(); 

avec

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

J’ai parcouru le tableau des points de terminaison en vérifiant que ma valeur de port n’était pas trouvée.

netstat! C’est un utilitaire de ligne de commande réseau livré avec Windows. Il montre toutes les connexions établies et tous les ports actuellement écoutés. Vous pouvez utiliser ce programme pour vérifier, mais si vous voulez faire cela à 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 goodies là-bas. Mais finalement, si vous voulez obtenir le même type d’informations que celles disponibles via la commande netstat, vous devrez vous connecter à P / Invoke …

Mise à jour: System.Net.NetworkInformation

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

Je n’ai pas pu trouver cette vieille pièce de code mais je pense que vous pouvez écrire quelque chose de similaire. Un bon début est de vérifier l’ API IP Helper . Google MSDN pour la fonction WINAPI GetTcpTable et utilisez P / Invoke pour énumérer les informations dont vous avez besoin.

Vous dites

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

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

Si ton

  c = new TcpClient(ip, port); 

échoue, alors rien n’y écoute. Sinon, il se connectera, même si une autre machine / application a un socket ouvert sur cette adresse IP et ce port.

Si je ne me trompe pas beaucoup, vous pouvez utiliser System.Network.whatever pour vérifier.

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

La manière canonique de vérifier est d’essayer d’écouter sur ce port. Si vous obtenez une erreur, ce port n’est pas ouvert.

Je pense que cela fait partie des raisons pour lesquelles bind () et listen () sont deux appels système distincts.

ipGlobalProperties.GetActiveTcpConnections() ne renvoie pas les connexions dans Listen State.

Le port peut être utilisé pour écouter, mais si personne n’est connecté, la méthode décrite ci-dessus ne fonctionnera pas.

Sachez que la fenêtre de temps entre votre vérification et le moment où vous essayez de vous connecter peut prendre le port – TOCTOU classique. Pourquoi n’essayez-vous pas de vous connecter? Si cela échoue, vous savez que le port n’est pas disponible.

Vous n’avez pas besoin de savoir quels ports sont ouverts sur votre ordinateur local 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: IP distante, numéro de port distant, IP locale, numéro de port local, mais vous devez uniquement connaître l’adresse IP distante et le numéro de port distant pour établir une connexion.

Lorsque vous créez une connexion TCP en utilisant

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

Votre système affectera automatiquement l’un des nombreux numéros de port locaux gratuits à votre connexion. Vous n’avez rien à faire. Vous pouvez également vérifier si un port distant est ouvert. mais il n’y a pas de meilleur moyen de le faire que d’essayer de s’y connecter.

  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; } 
 test_connection("ip", port); public void test_connection(Ssortingng 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."); } } } 

Parmi les 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(); 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 

Essayez ceci, dans mon cas, le numéro de port de l’object créé n’était pas disponible, alors

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