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

API standards et tierces Java Discussion :

Communication bidirectionnelle entre 2 postes distants par Socket


Sujet :

API standards et tierces Java

  1. #1
    Membre chevronné
    Avatar de tails
    Homme Profil pro
    Inscrit en
    Novembre 2003
    Messages
    799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 799
    Points : 2 148
    Points
    2 148
    Billets dans le blog
    15
    Par défaut Communication bidirectionnelle entre 2 postes distants par Socket
    Bonjour

    Je voudrais d'avance m'excuser si je pose ma question dans la mauvaise rubrique.

    J'ai l'intention de réaliser un simple client de d'échec en Java, permettant de jouer entre postes distants. A titre de test, je voudrais commencer par un simple test d'émission/de réception d'entiers. Le problème, c'est que je ne sais comment m'y prendre.

    • J'ai pensé au protocole Upnp : mais je n'arrive pas à synchroniser l'envoi et la réception de données entre 2 postes (j'ai utilisé le framework Cling). De plus, j'ai un peu peur que tous les postes ne puissent pas passer par Upnp.
    • J'ai pensé à du développement P2P : par JXTA notamment, mais les librairies sont complexes à utiliser et les documentations ne sont pas trop nombreuses (y compris dans la langue de Shakespear)
    • J'ai en fin pensé à passer par un serveur PHP dont je code la fonctionnalité tout en conservant le client en code Java, à coder en J2EE ou aussi en GAE. Le problème c'est que je ne sais pas comment je peux faire pour mettre en relation deux postes connectés sur le serveur, sans qu'aucun des postes ait à connaître l'adresse ip de l'autre


    A priori je partirais plus sur le fait de réaliser un serveur PHP où l'on se connecte, pour mettre en relation les joueurs ayant le client Java. Mais je ne sais pas si je que je cherche à faire est possible.

    Auriez-vous des pistes à me donner ? (Que ce soit sur la solution Upnp, client/serveur ou P2P). Je vous remercie d'avance.

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 552
    Points : 21 608
    Points
    21 608
    Par défaut
    Citation Envoyé par tails Voir le message
    J'ai en fin pensé à passer par un serveur PHP dont je code la fonctionnalité tout en conservant le client en code Java, à coder en J2EE ou aussi en GAE. Le problème c'est que je ne sais pas comment je peux faire pour mettre en relation deux postes connectés sur le serveur, sans qu'aucun des postes ait à connaître l'adresse ip de l'autre
    C'est la raison pour laquelle tous les jeux vidéos ont un système de "création de partie" avec un salon d'attente pour chaque partie, où les gens viennent se rejoindre en indiquant le nom ou l'adresse du salon, ou en se cherchant par nom d'utilisateurs.

    Parce que c'est une manière concrète de matérialiser le besoin des clients, de savoir avec quels autres clients ils vont parler.

    Une autre solution à la mode avec Minecraft, c'est d'installer un VPN genre hamachi entre les deux machines clientes, et que les deux programmes se cherchent avec une autodétection par broadcast sur le LAN de ce VPN.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre chevronné
    Avatar de tails
    Homme Profil pro
    Inscrit en
    Novembre 2003
    Messages
    799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 799
    Points : 2 148
    Points
    2 148
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par thelvin Voir le message
    C'est la raison pour laquelle tous les jeux vidéos ont un système de "création de partie" avec un salon d'attente pour chaque partie, où les gens viennent se rejoindre en indiquant le nom ou l'adresse du salon, ou en se cherchant par nom d'utilisateurs.

    Parce que c'est une manière concrète de matérialiser le besoin que les clients ont besoin de savoir avec quels autres clients ils vont parler.
    Ah oui : c'est vrai que la plupart des serveurs d'échec fonctionnent sur un principe similaire (requête de partie/réponse à la requête). Et c'est justement le fait qu'on ne puisse pas directement jouer entre amis qui m'a amené à tenter ce développement.

    Citation Envoyé par thelvin Voir le message
    Une autre solution à la mode avec Minecraft, c'est d'installer un VPN genre hamachi entre les deux machines clientes, et que les deux programmes se cherchent avec une autodétection par broadcast sur le LAN de ce VPN.
    Cela m'a l'air très intéressant. Je viens de voir un article sur Korben qui en parle, je vais donc pouvoir me lancer dans des investigations, et je l'espère, des expérimentations par la suite. Reste à trouver comment m'en sortir depuis Ubuntu (il semble qu'il y ait une béta 2 sur mon système favori : mais je vais regarder cela de plus près).
    L'installation et l'utilisation sur Ubuntu (Gnome) est très simple (en installant Hamachi et le client graphique Haguichi).

    Merci

  4. #4
    Membre chevronné
    Avatar de tails
    Homme Profil pro
    Inscrit en
    Novembre 2003
    Messages
    799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 799
    Points : 2 148
    Points
    2 148
    Billets dans le blog
    15
    Par défaut Mise en relation des deux postes.
    Je n'ai pas encore pu tester avec une personne distante, mais normalement je pense que chaque personne devrait avoir l'adresse ip "de substitution" de l'autre. Appelons les deux personnes P1 (adresse A1) et P2 (adresse A2).

    Cette étape résolue, il me faut encore trouver un moyen efficace pour initialiser les Sockets des deux instances du programme que j'ai codé (sur les deux postes éloignés).

    Admettons que :
    • A la fois P1 et P2 soient connectés sur un salon à travers Hamachi, et ont les adresses A1 et A2.
    • Les deux personnes P1 et P2 ont déjà démarré le programme de jeu.
    • C'est P1, qui en premier, lance le menu pour démarrer une partie avec P2.


    Si il sera alors simple de créer la Socket pointant sur A2 du côté de P1 :
    1. Comment faire en sorte que juste après ceci, le programme côté P2 puisse créer une Socket pointant sur A1 ?
    2. Et surtout, comment être sûr que les Sockets soient initialisées des deux côtés avant de pouvoir démarrer la partie ?
    3. Enfin, comment détecter le fait que l'une des Sockets soit coupée (connexion interrompue) et autoriser une attente d'un certain temps le temps que la personne concernée se reconnecte (avant d'éventuellement annuler définitivement la partie) ?


    Je vous remercie d'avance.

  5. #5
    Membre expérimenté
    Avatar de yotta
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Septembre 2006
    Messages
    1 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 088
    Points : 1 540
    Points
    1 540
    Par défaut Peut-être une piste...
    Dans le cas ou votre programme évolue sur un réseau LAN (VPN), Null besoin de machine tier pour héberger les parties.
    Voilà l'idée :
    Partons du principe suivant,
    Joueur J1 et joueur J2 désirent faire une partie. Dans ce scénario, J1 sera le premier à démarrer le programme sur sa

    machine. Puis J2 démarrera le sien. Au préalable, J1 et J2 seront connectés en VPN.
    Au lancement du programme de J1, un message de type broadcast (via DatagramSocket) est envoyé sur le réseau, mais comme

    il est le premier, pas de réponse...
    Il s'autoproclame hébergeur, et crée un ServerSocket prèt à accueillir toute connexion pour une partie. Dans le même

    temps, il met en écoute un DatagramSocket (sur le port broadcast 5600 fonctionnel chez moi) pour réceptionner les

    messages broadcast des autres programmes qui se lanceront après lui, ou qui lui répondent.
    J2 lance alors son programme, ce dernier emmet son message broadcast que J1 réceptionne, et il lui répond "Ok". Le

    programme de J2 présente alors dans sa liste de joueur disponible le joueur J1, et de son côté, le programme de J1

    ajoute dans sa liste de joueurs demandeur J2.
    Les deux programmes sont lancés, et les deux joueurs se voient. Le programme J1 étant autoproclamé hébergeur, J2

    sélectionne J1 dans sa liste et demande à se connecter, cette fois avec une connexion directe par Socket afin

    d'initialiser le dialogue du jeu.
    Si l'on désire permettre uniquement des parties uniques, il suffit de stopper l'écoute de message broadcast et

    d'entretenir le dialogue du jeu. Dans le cas contraire, il faudra isoler chaque partie dans son propre Thread, et

    continuer d'écouter pour héberger d'autres parties.

    Moralité, la gestion des parties se fait via les DatagramSocket, et les parties en Socket.


    Voici un exemple de code qui emet un message Broadcast et attend 50 millisecondes une réponse:

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    void emetMessage() {
    	DatagramSocket emeteur;
    	byte[] AdresseDeBroadcast = { (byte)255 , (byte)255 , (byte)255 , (byte)255 };
    	try {
    		InetSocketAddress broadcast = new InetSocketAddress(InetAddress.getByAddress(AdresseDeBroadcast), 5600);
    		byte[] messageInitial = new String("Message a envoyer à tout le monde").getBytes();
    		DatagramPacket EmissionBroadcast = new DatagramPacket(messageInitial, messageInitial.length, broadcast);
    		emeteur = new DatagramSocket();
    		emeteur.setBroadcast(true);
    		emeteur.send(EmissionBroadcast);
    		ecouteReponse();
    		}
    	catch (Exception e) {
    		System.out.println("Erreur lors de l'envoie de données broadcast. Détails :");
    		e.printStackTrace();
    		}
    	}
     
    void ecouteReponse() {
     
    	DatagramSocket ecouteur = new DatagramSocket(5600);
    	ecouteur.setSoTimeout(50);
    	byte[] messageReceptionne;
    	DatagramPacket recepteur;
    	String valeur;
    	int cpt;
    	try {
    		messageReceptionne = new byte[1000]; // Plus selon la longueur de vos messages.
    		recepteur = new DatagramPacket(messageReceptionne, messageReceptionne.length());
    		ecouteur.receive(recepteur);
    		valeur = new String(recepteur.getData());
    		System.out.println(valeur);
    		// Traitement de l'information...
    		// Je ne suis pas le premier, j'ajoute celui qui m'a répondu dans ma liste...
    		...
    		...
    		.
    		}
    	catch (Exception e) {
           		System.out.println("Pas de réponse au message Broadcasr : Autoproclamation d'hébergement.");
    	        // Selon scénario, je suis le premier => création du ServerSocket
    		// Attente de message Broadcast...
    		...
    		...
    		.
    		}	
    	}


    Qu'en pensez-vous ?
    Une technologie n'est récalcitrante que par ce qu'on ne la connait et/ou comprend pas, rarement par ce qu'elle est mal faite.
    Et pour cesser de subir une technologie récalcitrante, n'hésitez surtout pas à visiter les Guides/Faq du site !

    Voici une liste non exhaustive des tutoriels qui me sont le plus familiers :
    Tout sur Java, du débutant au pro : https://java.developpez.com/cours/
    Tout sur les réseaux : https://reseau.developpez.com/cours/
    Tout sur les systèmes d'exploitation : https://systeme.developpez.com/cours/
    Tout sur le matériel : https://hardware.developpez.com/cours/

  6. #6
    Membre chevronné
    Avatar de tails
    Homme Profil pro
    Inscrit en
    Novembre 2003
    Messages
    799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 799
    Points : 2 148
    Points
    2 148
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par pursang Voir le message
    Dans le cas ou votre programme évolue sur un réseau LAN (VPN), Null besoin de machine tier pour héberger les parties.
    Voilà l'idée :
    Partons du principe suivant,
    Joueur J1 et joueur J2 désirent faire une partie. Dans ce scénario, J1 sera le premier à démarrer le programme sur sa

    machine. Puis J2 démarrera le sien. Au préalable, J1 et J2 seront connectés en VPN.
    Au lancement du programme de J1, un message de type broadcast (via DatagramSocket) est envoyé sur le réseau, mais comme

    il est le premier, pas de réponse...
    Il s'autoproclame hébergeur, et crée un ServerSocket prèt à accueillir toute connexion pour une partie. Dans le même

    temps, il met en écoute un DatagramSocket (sur le port broadcast 5600 fonctionnel chez moi) pour réceptionner les

    messages broadcast des autres programmes qui se lanceront après lui, ou qui lui répondent.
    J2 lance alors son programme, ce dernier emmet son message broadcast que J1 réceptionne, et il lui répond "Ok". Le

    programme de J2 présente alors dans sa liste de joueur disponible le joueur J1, et de son côté, le programme de J1

    ajoute dans sa liste de joueurs demandeur J2.
    Les deux programmes sont lancés, et les deux joueurs se voient. Le programme J1 étant autoproclamé hébergeur, J2

    sélectionne J1 dans sa liste et demande à se connecter, cette fois avec une connexion directe par Socket afin

    d'initialiser le dialogue du jeu.
    Si l'on désire permettre uniquement des parties uniques, il suffit de stopper l'écoute de message broadcast et

    d'entretenir le dialogue du jeu. Dans le cas contraire, il faudra isoler chaque partie dans son propre Thread, et

    continuer d'écouter pour héberger d'autres parties.

    Moralité, la gestion des parties se fait via les DatagramSocket, et les parties en Socket.


    Voici un exemple de code qui emet un message Broadcast et attend 50 millisecondes une réponse:

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    void emetMessage() {
    	DatagramSocket emeteur;
    	byte[] AdresseDeBroadcast = { (byte)255 , (byte)255 , (byte)255 , (byte)255 };
    	try {
    		InetSocketAddress broadcast = new InetSocketAddress(InetAddress.getByAddress(AdresseDeBroadcast), 5600);
    		byte[] messageInitial = new String("Message a envoyer à tout le monde").getBytes();
    		DatagramPacket EmissionBroadcast = new DatagramPacket(messageInitial, messageInitial.length, broadcast);
    		emeteur = new DatagramSocket();
    		emeteur.setBroadcast(true);
    		emeteur.send(EmissionBroadcast);
    		ecouteReponse();
    		}
    	catch (Exception e) {
    		System.out.println("Erreur lors de l'envoie de données broadcast. Détails :");
    		e.printStackTrace();
    		}
    	}
     
    void ecouteReponse() {
     
    	DatagramSocket ecouteur = new DatagramSocket(5600);
    	ecouteur.setSoTimeout(50);
    	byte[] messageReceptionne;
    	DatagramPacket recepteur;
    	String valeur;
    	int cpt;
    	try {
    		messageReceptionne = new byte[1000]; // Plus selon la longueur de vos messages.
    		recepteur = new DatagramPacket(messageReceptionne, messageReceptionne.length());
    		ecouteur.receive(recepteur);
    		valeur = new String(recepteur.getData());
    		System.out.println(valeur);
    		// Traitement de l'information...
    		// Je ne suis pas le premier, j'ajoute celui qui m'a répondu dans ma liste...
    		...
    		...
    		.
    		}
    	catch (Exception e) {
           		System.out.println("Pas de réponse au message Broadcasr : Autoproclamation d'hébergement.");
    	        // Selon scénario, je suis le premier => création du ServerSocket
    		// Attente de message Broadcast...
    		...
    		...
    		.
    		}	
    	}


    Qu'en pensez-vous ?
    Bonjour

    Merci beaucoup pour la piste : j'avais examiné des sources déjà publiées, et elles n'utilisaient pas de DatagramSocket (dont tu viens de m'apprendre l'utilisation et la finalité). Je pense que ta solution est plus propre et méthodique. Et cela colle bien avec le fait que je veuille utiliser Hamachi pour établir un VPN privé.

    Malheureusement, les personnes qui m'avaient dit qu'elles m'aideraient à tester l'infrastructure Hamachi + Prog perso semblent s'être désistées.

    Mais je mets quand même la discussion comme résolue, car je suis persuadé de pouvoir m'en sortir avec ta proposition.

    Merci

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

Discussions similaires

  1. Communication entre deux postes distants
    Par Fubautsuw dans le forum Général Java
    Réponses: 4
    Dernier message: 02/05/2015, 16h54
  2. communication bidirectionnel entre le serveur et l'application
    Par Nono1nd dans le forum API standards et tierces
    Réponses: 11
    Dernier message: 11/03/2014, 04h43
  3. Connexion UDP entre 2 postes distants
    Par leghola dans le forum Protocoles
    Réponses: 9
    Dernier message: 16/04/2013, 11h06
  4. Communication réseau entre 2 postes
    Par abdelghani_k dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 22/07/2008, 19h20
  5. Communication par socket TCP entre module windows et linux
    Par =o0 MOH =0o= dans le forum Réseau
    Réponses: 2
    Dernier message: 29/03/2007, 17h04

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