1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2014
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2014
    Messages : 121
    Points : 89
    Points
    89

    Par défaut Mettre en écoute un port

    Bonjour,

    J'ai un projet, ou je dois mettre en écoute un port précis, pour que lorsque le serveur émet un message, celui ci apparaisse chez le client.

    Je vais travailler sur un réseau de plusieurs millier de machine, j'ai donc opté pour utiliser le protocole UDP, qui me permet de mettre en écoute le port en local, sans avoir à me connecter à un serveur.

    Pour le moment, voilà le code que j'ai :

    //Client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
        class Program
        {
            private const int listenPort = 11000;
            private static void StartListener()
            {
                bool done = false;
     
                UdpClient listener = new UdpClient(listenPort);
                IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
     
                try
                {
                    while (!done)
                    {
                        Console.WriteLine("Waiting for broadcast");
                        byte[] bytes = listener.Receive(ref groupEP);
     
                        Console.WriteLine("Received broadcast from {0} :\n {1}\n",
                            groupEP.ToString(),
                            Encoding.ASCII.GetString(bytes, 0, bytes.Length));
                    }
     
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                finally
                {
                    listener.Close();
                }
            }  
     
            static void Main(string[] args)
            {
                StartListener();  
            }
        }
    //Serveur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
        class Program
        {
            private const int listenPort = 11000;
            private static void StartListener()
            {
                bool done = false;
     
                UdpClient listener = new UdpClient(listenPort);
                IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
     
                try
                {
                    while (!done)
                    {
                        Console.WriteLine("Waiting for broadcast");
                        byte[] bytes = listener.Receive(ref groupEP);
     
                        Console.WriteLine("Received broadcast from {0} :\n {1}\n",
                            groupEP.ToString(),
                            Encoding.ASCII.GetString(bytes, 0, bytes.Length));
                    }
     
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                finally
                {
                    listener.Close();
                }
            }  
     
            static void Main(string[] args)
            {
                StartListener();  
            }
        }
    J'aurai plusieurs question.

    L'application doit tournée en arrière plan sans arrêt, sans consommer de ressource (ram ou autre), est-ce "compatible" avec la boucle while présente dans le code client ? Ou il faut la remplacer par quelque chose d'autre ?

    J'aimerai stocké dans les logs, les postes qui n'ont pas reçu le message.

    J'ai donc pensé, lorsque le client reçoit un message, il ré émet, à l'adresse IP qui viens de lui envoyer le message, un message. Sachant que les messages diffusé par le serveur seront émis par broadcast,
    pensez vous que si tout les clients ré émettent en même temps, le serveur tombe ?
    Il me faudra plusieurs Thread ? l'un en envoi l'autre en réception, côté serveur ?

    Merci d'avance pour les réponses !

  2. #2
    Rédacteur/Modérateur

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    1 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 1 416
    Points : 4 774
    Points
    4 774
    Billets dans le blog
    5

    Par défaut

    Bonjour,

    Si je résume bien, tu aimerais pouvoir mettre en place un broadcast avec accusé de réception ?

    Pour le broadcast, le choix de l'UDP peut effectivement être pertinent, dans la mesure où TCP ne supporte pas le broadcast. Cela permet d'avoir un seul message envoyé pour x machines.

    Maintenant, la problématique est d'accuser la réception du message par les clients. Deux problématiques :
    • il faut que ton serveur connaisse a priori la liste des clients (sinon un client ne recevant jamais de message ne sera pas détecté par le serveur) ;
    • il faut que chaque client envoie un message au serveur (et donc établisse une connexion).


    Le risque, si tu envoies l'accusé réception par UDP, c'est que si tous les clients le font en même temps (ce qui a de grande chance d'arriver vu qu'il s'agira d'une réponse à un broadcast), tu vas avoir un risque de collisions très important. Et donc du point de vue serveur, beaucoup de clients n'ayant pas reçu le message alors qu'en réalité, c'est le cas.

    Ce qui inciterait donc à transmettre la réponse par TCP. Mais dans ce cas, d'un point de vue trame réseau, tu vas avoir :
    • une trame UDP en broadcast ;
    • x trames TCP envoyés par le client vers le serveur ;
    • x accusé réception TCP envoyés par le serveur au client.


    Du coups, on voit bien que si on utilise TCP, alors il y aura une communication dans les deux sens pour gérer l'accusé réception. Aussi, ne serait-il pas plus judicieux dans ce cas d'établir une connexion entre le serveur et chaque client, et que le serveur envoie les messages directement à chaque client au lieu d'utiliser un broadcast UDP ? Ainsi, cela sera plus simple car tu délègues la gestion de la réception à TCP, ainsi que le problème de la collision.

    Voilà pour la théorie.

    En pratique, cela va dépendre de beaucoup de choses (liste non exhaustives) :
    • la fréquence d'envoie des messages ;
    • la taille des messages envoyés ;
    • les contraintes temporelles des applications ;
    • la qualité et la vitesse du réseau ;
    • le nombre de machines connectées ;
    • l'importance des données (est-ce grave si des paquets se perdent ?) ;
    • les faux positifs de non réception (est-ce grave si le serveur croit qu'un client n'a pas reçu un paquet alors qu'il l'a reçu ?) ;
    • la possibilité de mutualiser les accusés de réception (on envoie un seul accusé pour x messages reçus).


    [EDIT]
    Du coup, je n'ai même pas répondu aux questions...
    pensez vous que si tout les clients ré émettent en même temps, le serveur tombe ?
    Il me faudra plusieurs Thread ? l'un en envoi l'autre en réception, côté serveur ?
    Est-ce que le serveur va tomber ? Cela dépend des traitements. Mais s'il s'agit juste de loguer un accusé réception, il n'y a pas beaucoup de risque.

    Sinon, l'utilisation de thread peut effectivement te faciliter la tâche.
    [/EDIT]
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2014
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2014
    Messages : 121
    Points : 89
    Points
    89

    Par défaut

    Bonjour,

    Tous d'abord, je te remercie pour la réponse !

    Ce qui me pose soucis avec le TCP, c'est de laisser la connexion ouverte toute la journée, tout les jours, car le message peut être envoyé à n'importe qu'elle moment.

    Ensuite, le serveur devra créer un thread par connexion, c'est à dire, au moins 3.000 postes(probablement bien plus). Sachant que j'aurai normalement, la possibilité d'avoir une liste de tout les réseaux, les ips, ainsi que les broadcaste en BDD.

    Pour t'es autres interrogations, il s'agit d'envoi exceptionnel, quelque chose qui risque de n'avoir lieux même pas une fois par an.

    Second souci, c'est que la propagation sur le réseau doit prendre moins de 15 secondes, malheureusement, je pense à mon avis, qu'il va plutôt s'agir d'une question de QoS. (UDP me permet quand même d'être plus rapide que TCP).

    Avec UDP, je m'attend forcément à des pertes, mais si cela ne touche pas énormément de poste, cela est négligeable.

    Pareil pour les logs, mais je comprend bien que je n'aurais rien de très précis, la question de l'utilité risque alors de ce poser.

  4. #4
    Rédacteur/Modérateur

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    1 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 1 416
    Points : 4 774
    Points
    4 774
    Billets dans le blog
    5

    Par défaut

    Citation Envoyé par bloups0 Voir le message
    Ce qui me pose soucis avec le TCP, c'est de laisser la connexion ouverte toute la journée, tout les jours, car le message peut être envoyé à n'importe qu'elle moment.
    Il y a un moyen de faire autrement, c'est d'inverser les rôles des clients et du serveur. Mais cela nécessite d'avoir connaissance des postes. En gros, chaque client écoute sur un port en TCP, et le serveur vient se connecter à chacun des clients lorsque c'est nécessaire.

    Aujourd'hui, chaque client écoute un port en UDP, cela ne serait donc pas très différent.

    Citation Envoyé par bloups0 Voir le message
    Ensuite, le serveur devra créer un thread par connexion, c'est à dire, au moins 3.000 postes(probablement bien plus). Sachant que j'aurai normalement, la possibilité d'avoir une liste de tout les réseaux, les ips, ainsi que les broadcaste en BDD.
    Pas forcément. On peut utiliser du pooling au niveau des threads. J'ai d'ailleurs écrit des articles sur l'utilisation du pool de thread.

    Citation Envoyé par bloups0 Voir le message
    Second souci, c'est que la propagation sur le réseau doit prendre moins de 15 secondes, malheureusement, je pense à mon avis, qu'il va plutôt s'agir d'une question de QoS. (UDP me permet quand même d'être plus rapide que TCP).
    A voir exactement ce qui doit prendre au plus 15s. L'envoi du message "broadcasté", ou la réception des accusés par le serveur ?

    Citation Envoyé par bloups0 Voir le message
    Avec UDP, je m'attend forcément à des pertes, mais si cela ne touche pas énormément de poste, cela est négligeable.

    Pareil pour les logs, mais je comprend bien que je n'aurais rien de très précis, la question de l'utilité risque alors de ce poser.
    Pour pouvoir quantifier les pertes, il faudrait procéder à un essai grandeur nature.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2014
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2014
    Messages : 121
    Points : 89
    Points
    89

    Par défaut

    Le souci, c'est qu'il va vraiment me falloir l'ip de tout les postes, et me connecté un par un, donc tram de connexion, le client(serveur) va me renvoyer une tram pour me dire OK, et ensuite je pourrais transmettre, sur 3000 postes, cela ne va pas surcharger le réseau ?

    Je vais aller lire l'article sur le pool threading.

    Ce qui doit prendre 15 secondes, c'est l'envoi du message sur tout les postes.

    Merci pour les réponses, cella m'aide a éclaircir quelques problématiques, ou en voir d'autre ^^.

  6. #6
    Rédacteur/Modérateur

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    1 416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 1 416
    Points : 4 774
    Points
    4 774
    Billets dans le blog
    5

    Par défaut

    Citation Envoyé par bloups0 Voir le message
    Le souci, c'est qu'il va vraiment me falloir l'ip de tout les postes, et me connecté un par un, donc tram de connexion, le client(serveur) va me renvoyer une tram pour me dire OK, et ensuite je pourrais transmettre, sur 3000 postes, cela ne va pas surcharger le réseau ?
    Tout dépend de la taille du message. Sachant que le message passait initialement en UDP, j'ai fait l'hypothèse que le message était petit. Donc est-ce que cela va pourrir le réseau ? Je ne pense pas. Sauf si c'est un réseau 56k !

    Citation Envoyé par bloups0 Voir le message
    Ce qui doit prendre 15 secondes, c'est l'envoi du message sur tout les postes.
    Dans ce cas, il est possible de privilégier l'envoi du message en utilisant le broadcast UDP. Dans un second temps, les clients se connectent en TCP au serveur pour accuser réception du message. Tu auras ainsi des log fiables.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  7. #7
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    février 2010
    Messages
    3 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : février 2010
    Messages : 3 352
    Points : 8 862
    Points
    8 862
    Billets dans le blog
    3

    Par défaut

    Il me semble qu'en UDP il est possible de detecter les clients, sans avoir une liste pre-definie.

    Autre point, tu peux regarder du cote de Pragmatic General Multicast (PGM) qui est plus fiable qu'UDP.
    Enfin, il y a toujours la solution du Message Bus, comme par exemple NServiceBus qui ne necessite pas de machine supplementaire et qui permet de mettre en place un mecanisme de publication/subscription.

    PGM et NServiceBus offrent une garantie sur la livraison des messages, contrairement a UDP.

    A voir si cela repond a tes contraintes.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige

  8. #8
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2014
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2014
    Messages : 121
    Points : 89
    Points
    89

    Par défaut

    Citation Envoyé par DotNetMatt Voir le message
    Il me semble qu'en UDP il est possible de detecter les clients, sans avoir une liste pre-definie.

    Autre point, tu peux regarder du cote de Pragmatic General Multicast (PGM) qui est plus fiable qu'UDP.
    Enfin, il y a toujours la solution du Message Bus, comme par exemple NServiceBus qui ne necessite pas de machine supplementaire et qui permet de mettre en place un mecanisme de publication/subscription.

    PGM et NServiceBus offrent une garantie sur la livraison des messages, contrairement a UDP.

    A voir si cela repond a tes contraintes.
    Merci a vous deux pour les réponses, je pense que j'ai les éléments suffisant pour le projet !

    Du coup François, je vais partir sur de l'UDP, est surement mettre en place une connexion TCP pour le retour.

    Je vais regarder ce que tu m'as donné DotNetMatt, mais pour cette fois, ce sera juste pour ma culture général !

    Passer une bonne journée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Apple risque de mettre Google AdMob à la porte de iAds
    Par Idelways dans le forum Actualités
    Réponses: 12
    Dernier message: 20/07/2010, 01h18
  2. Empêcher l'écoute de ports
    Par allergique dans le forum VB.NET
    Réponses: 13
    Dernier message: 26/12/2009, 20h43
  3. Écoute de ports
    Par thomasg44 dans le forum Général Java
    Réponses: 10
    Dernier message: 17/02/2009, 23h52
  4. [Sécurité] PHP et l'écoute de port
    Par Qamalito dans le forum Sessions
    Réponses: 9
    Dernier message: 25/06/2007, 09h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo