web-dev-qa-db-fra.com

Vérifier si un port est ouvert

Je n'arrive pas à trouver quoi que ce soit qui me dit si un port de mon routeur est ouvert ou non .. Est-ce même possible?

Le code que j'ai en ce moment ne semble pas vraiment fonctionner ...

private void ScanPort()
{
    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);
    }
}
19
Yuki Kutsuya

Essaye ça:

using(TcpClient tcpClient = new TcpClient())
{
    try {
        tcpClient.Connect("127.0.0.1", 9081);
        Console.WriteLine("Port open");
    } catch (Exception) {
        Console.WriteLine("Port closed");
    }
}

Vous devriez probablement changer 127.0.0.1 en quelque chose comme 192.168.0.1 ou quelle que soit l'adresse IP de votre routeur.

31
Clinton Ward

Une meilleure solution où vous pouvez même spécifier un délai d'attente:

bool IsPortOpen(string Host, int port, TimeSpan timeout)
{
    try
    {
        using(var client = new TcpClient())
        {
            var result = client.BeginConnect(Host, port, null, null);
            var success = result.AsyncWaitHandle.WaitOne(timeout);
            if (!success)
            {
                return false;
            }

            client.EndConnect(result);
        }

    }
    catch
    {
        return false;
    }
    return true;
}

Et en F #:

let IsPortOpen (Host: string, port: int, timeout: TimeSpan): bool =
    let canConnect =
        try
            use client = new TcpClient()
            let result = client.BeginConnect(Host, port, null, null)
            let success = result.AsyncWaitHandle.WaitOne(timeout)
            match success with
            | false -> false
            | true ->
                   client.EndConnect(result)
                   true
        with
        | _ -> (); false
    canConnect
18
ympostor

Il n'y a aucun moyen de savoir si le port est transféré dans votre routeur, sauf si un programme écoute ce port.

Comme vous pouvez le constater dans la réponse Clinton, la classe .Net utilisée est TcpClient, car vous utilisez un socket TCP pour vous connecter. C'est ainsi que les systèmes d'exploitation établissent des connexions: à l'aide de sockets. Cependant, un routeur ne fait que transmettre les paquets (couche 3 du modèle OSI). Dans votre cas, votre routeur fait ce qu’on appelle: NAT. C'est une adresse IP publique partagée par une ou plusieurs adresses IP privées. C'est pourquoi vous effectuez une redirection de port.

Il peut y avoir beaucoup de routeurs dans le chemin des paquets et vous ne saurez jamais ce qui s’est passé.

Imaginons que vous envoyez une lettre de manière traditionnelle. Peut-être que vous pouvez écrire dans la lettre que le destinataire doit vous répondre afin de vérifier qu'il/elle est là (vous et le destinataire sont les sockets). Si vous recevez une réponse, vous serez sûr de sa présence, mais si vous ne recevez rien, vous ne savez pas si le facteur (dans votre cas, le routeur) a oublié de remettre la lettre, ou le destinataire n’a pas a répondu. De plus, vous ne saurez jamais si le facteur a demandé à un ami de remettre cette lettre. De plus, le facteur n’ouvrira pas la lettre pour savoir s’il peut répondre parce que vous attendez une réponse. Tout ce que vous pouvez faire est d’attendre quelque temps pour recevoir la réponse. Si vous ne recevez rien pendant cette période, vous supposerez que le destinataire n’est pas celui où vous avez envoyé la lettre. C'est un "timeout".

J'ai vu une réponse mentionnant le logiciel nmap. C'est vraiment un très bon et complexe soft, mais je pense que cela fonctionnera de la même manière. Si aucune application n'écoute dans ce port, il n'y a aucun moyen de savoir si elle est ouverte ou non.

S'il vous plaît, laissez-moi savoir si j'étais clair.

2
Ignacio

Si vous vous connectez à l'adaptateur loopback - localhost ou 127.0.0.1 ( il n'y a pas d'endroit comme 127.0.0.1! ), il est peu probable que vous alliez au routeur. Le système d'exploitation est suffisamment intelligent pour reconnaître qu'il s'agit d'une adresse spéciale. Je ne sais pas si cela vaut également si vous spécifiez réellement la "véritable" adresse IP de votre machine.

Voir aussi cette question: Quel est le but de la carte de bouclage Microsoft?

Notez également que l'exécution de traceroute localhost (tracert localhost sous Windows) indique que le seul nœud de réseau impliqué est votre propre ordinateur. Le routeur n'est jamais impliqué.

2
Nicholas Carey

Un transfert de port sur le routeur ne peut pas être testé depuis le LAN, vous devez vous connecter depuis le côté WAN (Internet) pour voir si un transfert de port fonctionne ou non.

Plusieurs sites Internet offrent des services pour vérifier si un port est ouvert:

Qu'est-ce que mon scanner de port IP

GRC | ShieldsUP!

Si vous souhaitez vérifier avec votre propre code, vous devez vous assurer que la connexion TCP/IP est redirigée via un proxy externe ou que vous configurez un tunnel. Cela n'a rien à voir avec votre code, c'est un réseau de base 101.

1
Antoine Megens
public static bool PortInUse(int  port)
{
    bool inUse = false;

    IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    IPEndPoint [] ipEndPoints = ipProperties.GetActiveTcpListeners();


    foreach(IPEndPoint endPoint in ipEndPoints)
    {
        if(endPoint.Port == port)
        {
            inUse = true;
            break;
        }
    }


    return  inUse;
}
1
Ravi Kumar G N

Pour moi, j'avais besoin d'un blocage jusqu'à ce que la connexion au port soit disponible ou après un certain nombre de tentatives Donc, j'ai compris ce code:

public bool IsPortOpen(string Host, int port, int timeout, int retry)
{
    var retryCount = 0;
    while (retryCount < retry)
    {
        if (retryCount > 0)
            Thread.Sleep(timeout);

        try
        {
            using (var client = new TcpClient())
            {
                var result = client.BeginConnect(Host, port, null, null);
                var success = result.AsyncWaitHandle.WaitOne(timeout);
                if (success)
                    return true;

                client.EndConnect(result);
            }
        }
        catch
        {
            // ignored
        }
        finally { retryCount++; }
    }

    return false;
}

J'espère que cela t'aides!

0
Mathieu Paquette