IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

trouver les hotes


Sujet :

C++Builder

  1. #1
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut trouver les hotes
    Bonjour,

    quelqu'un pourait-il m'indiquer le principe pour trouver (sur le reseau local) tous les serveurs correspondant à l'application?

    exemple : comment un jeu trouve-t-il toutes les adresses des serveurs qui hebergent une partie ?

    merci de vos indications

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 19
    Points : 25
    Points
    25
    Par défaut re
    Tu as deux méthodes :

    1° la méthode brute
    La méthode brute consiste a passer toutes les adresses du réseau local pour voir si l'un deux répond sur le port du serveur. C'est une solution 'auto' mais qui peut générer beaucoup de traffic et prendre un temps bête.

    2° la méthode "annuaire"
    Tu as un serveur central qui sert d'annuaire. Dès qu'un serveur est lancé, il se connecte sur le central pour lui signaler qu'il est online. Le serveur, tant qu'il est connecté, peut signaler un refresh toutes les 10 minutes (par exemple) au central. Si le central voit qu'un serveur n'a pas fait son refresh, il le vire de l'annuaire. Lorsque ton client veut se connecter à un serveur, il interroge le central pour avoir la liste des serveurs disponibles.

    Il me semble que sur Counter Strike, c'est le prinicpe du serveur central (le serveur WON je crois)

  3. #3
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    ok donc dans le cadre de la "methode brute", il suffit de tenter une connection socket (try-catch?) de toutes les adresses du reseau local auquel on appartient. L'operation me semble gourmande en ressource mais je tente le coup (apres tout counterstrike procede comme ca en LAN je croi)


    merci

  4. #4
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    heu au fait... comment on fait pour obtenir l'adresse ip de la machine local (pas localhost ni 127.0.0.1) ainsi que le masque sous reseau ?

    sans ca je voi pas comment faire ma boucle de parcour des adresses locales ...


  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 19
    Points : 25
    Points
    25
    Par défaut re
    Sous Linux : ça se trouve dans un fichier /proc
    Sous Windows : ça doit se trouver dans la base de registre au niveau de la configuration réseau mais alors où exactement..., il faut faire une recherche sur Google ou dans le forum.

    Ou alors, tu fais un regedit et tu fais une recherche sur ton adresse de réseau LAN, et tu regardes quel est la clé qui correspont à cet info. Mais attention en jouant avec la base de registre, les paramètres peuvent être différents d'un windows à l'autre (c'est à vérifier)

  6. #6
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    ok j'ai trouver comment avoir l'ip (ClientSocket->Socket->RemoteAddress)

    mais j'ai encore des soucis ....

    voila comment je procede:

    un boucle qui pour chaque adresse ip, ouvre la socket, la ferme et passe a la suivante.
    le try catch sur socket->open() ne revoi pas d'erreur sur la connection , donc j'utilise l'envennement OnClientConnect pour savoir si une connection s'est ouverte.

    mon probleme:


    lorsque l'evennement OnClientConnect survient, la valeur de la propriete Adresse est toujours 254 (la valeur prise à la fin de ma boucle)
    autrement dit, le programme effectue la boucle qui scanne les ip du reseau, puis les evennements sur l'objet clientsocket arrivent (donc de maniere asynchrone)

    avec ce decalage je peux pas savoir quelle adresse a repondu ...

    ->j'ai lu quelque chose sur le handle dans la doc mais j'ai pas compris et je sais pas si c'est la solution à mon probleme

    ->une autre solution me vien a l'esprit; trouver un moyen de mettre en attente le programme juste apres le ClientSocket->Open() pour attendre que l'evennement OnClientConnect ou OnClientError survienne ... mais je n'ai aucune idee sur le procédé.

    un peu d'aide serait la bienvenue

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 19
    Points : 25
    Points
    25
    Par défaut re
    Il me semble que lorsqu'un socket est ouvert, tu peux obtenir l'adresse IP du serveur sur lequel il est connecté. L'event OnClientConnect te fournit un Socket en paramètre je crois. Sur ce socket-là, tu peux avoir l'adresse.

    La valeur de la propriété Adresse dont tu parles (celle qui est à 254), tu la prends d'où ? Du ClientSocket ?

    Evites de mettre des choses en attente, ce serait, à mon avis, une grosse perte de temps.

  8. #8
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    c'est bien ca mon probleme

    Socket->RemoteAddress de l'evennement OnClientConnect me retourne l'ip 255 (soit celle de ma fin de boucle)

    ce qui veux dire que ce n'est pas le socket qui a reussi a se connecté que j'utilise mais le dernier que j'ai ouvert ...

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 19
    Points : 25
    Points
    25
    Par défaut re
    Bon, essaies cette solution :
    A chaque fois que tu lances un ClientSocket pour ce connecter, tu notes dans un tableau à deux entrée l'handle du socket et le nr d'hote que tu testes.
    De cette manière, lorsque tu reçois une connection (OnClientConnect), tu récupères le handle de socket et tu le compare à ta liste handle/nr hote.

    Ou alors, je viens de me rappeler qqch, tu peux définir les ClientSocket en bloquant (!= du non-bloquant).

    Ce sont deux voies qui me viennent à l'esprit...

  10. #10
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    j'ai essayer la methode de mise en attente (lance une requete sur une ip et attente de la reponse pour tester une autre ip) mais c'est beaucoup trop lent! (1min pour 7 ip ...)

    j'ai essayer aussi avec un handle mais c'est le meme probleme qu'avec l'adresse du socket , c'est a dire que sur les evennement OnClientConnect ou OnClientError, je handle recu est celui de la derniere socket ouverte (ip .254)

    je suis dans une impasse ...

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 19
    Points : 25
    Points
    25
    Par défaut re
    Il y a toujours une solution ;-)

    Je viens de penser à une chose, lorsque tu as un OnClientConnect, pq le serveur ne t'enverrais pas une ligne d'identification avec son adresse IP ?

    Le serveur peut lire son adresse IP dans la base de registre et dès que le serveur reçoit une connection entrante sur le port, il balances un ID sur le socket que tu peux réceptionner au niveau de ton client pour le mettre dans une liste de serveur disponible.

    Qu'en penses-tu ?

  12. #12
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    merci mais je ne veux pas recevoir de reponse de la part des serveurs ...

    enfin j'ai trouvé !!

    pour info voila la soluce :

    Recherche des machines connectées au reseau local:
    1. je recupere l'ip locale
    2. avec une boucle, pour chaque ip du reseau (1 à 254) j'envoi un ping avec l'objet TIdIcmpClient
    3. a chaque ip qui me repond OnIdIcmpClientReply, je la mémorise dans un tableau

    Recherche des machines locales qui sont des serveurs:
    1. j'active mon objet TcpClient sur la premiere adresse de mon tableau
    2. lorque je recoi une reponse alors je passe à la suivante (OnTcpClientError et OnTcpClientConnect), je stock bien sur l'adresse si elle a répondu

    et je boucle ansi pour toutes les adresses de mon tableau.


    BILAN : 15-20sec de recherche pour scaner le reseau et trouver les serveurs, et 5-10 sec pour rafraichir (rechercher a partir du tableau de machines connectées)

    BUG: pendant ces 20sec, le programme est comme planté (on ne peut rien faire tout est bloqué)

  13. #13
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Bonjour,

    Juste un commentaire. Tu suppose que le réseau est un réseau de classe C, c'est à dire que seuls les 8 derniers bits sont les identifiants d'hôte. Mais si quelqu'un décide de faire tourner ton appli sur un réseau de classe B ? ou pire, A (on peut rêver...)

    Je dis peut-être une bétise, mais est-ce qu'un envoi de broadcast de la part du client ne serait pas plus approprié ? Les serveurs recevant ce broadcast le traiteraient et renveraient une réponse. Le client pourrait ainsi construire sa liste de serveurs au gré des réponses reçues...
    De plus, la technique du broadcast a un certain avantage, vu qu'elle permet de se libérer des caractéristiques du réseau, et que cela réduit finalement le nombre de requêtes, et le temps nécessaire.

    Cordialement,

    Arnaud

  14. #14
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    j'y ai songé mais une ouverture TCP vers une adresse de broadcast me revoi toujours une erreur ... peut etre que je ne sais pas le faire ...

    quand aux adresses autres que de classe C, c'est qu'une question de boucle , suffit de boucler sur les 3 derniers octets. (sachant que je met 20sec max pour scaner une classe C, je mettrai ... heuu.. c dur la ... 360h pour une classe A )

    donc je prefere verifier seulement le dernier octet

  15. #15
    Membre actif Avatar de Général03
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2006
    Messages : 848
    Points : 283
    Points
    283
    Par défaut
    J'ai bien suivi vos explication mais je n'arrive pas à utiliser la commande Ping().

    Je n'arrive pas à utiliser OnIdIcmpClientReply que vous préconisez

    L'évenement OnReply de IdIcmpClient me repond même si l'adresse pinger n'est pas présente.

    Quelqu'un pourrait m'aider

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

Discussions similaires

  1. [image] trouver les couleurs les plus présentes
    Par giminik dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 25/01/2005, 03h35
  2. [langage] Trouver les fichiers sans la case
    Par nledez dans le forum Langage
    Réponses: 2
    Dernier message: 22/12/2004, 12h07
  3. Trouver les redirections dans des traces
    Par severine dans le forum Développement
    Réponses: 3
    Dernier message: 21/04/2004, 18h51
  4. [GUI] Ou trouver les standard ?
    Par Braim dans le forum Windows
    Réponses: 5
    Dernier message: 01/10/2003, 08h13

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