Impossible d'obtenir le message du client

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonsoir ! :)

Je commence juste avec les Sockets (enfin… je suis depuis ce matin sur le même problème :p ) en Java, et je rencontre un problème.

Avant de vous expliquez, voici mon code :

 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class GuiFrame extends JFrame implements Runnable, ActionListener {

    private final static String serverIp = "192.168.1.22";
    private final static int serverPort = 2500;

    private ServerSocket serverSocket;
    private Socket clientSocket;

    private JButton hostButton;
    private JButton joinButton;

    private boolean ready = false;
    private boolean host = false;

    public GuiFrame() {
        super.setSize(800, 600);
        super.setTitle("Castle Goblins");

        super.setLocationRelativeTo(null);
        super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        getContentPane().setLayout(new FlowLayout());

        hostButton = new JButton("Héberger");
        joinButton = new JButton("Rejoindre");

        hostButton.addActionListener(this);
        joinButton.addActionListener(this);

        getContentPane().add(hostButton);
        getContentPane().add(joinButton);

        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == hostButton) { // Serveur
            try {
                serverSocket = new ServerSocket(serverPort);
                ready = true;
                host = true;
                System.out.println("Serveur Socket : OK");
            } catch (IOException ex) { System.err.println(ex.getMessage()); }
        }

        if (e.getSource() == joinButton) { // Client
            try {
                clientSocket = new Socket(serverIp, serverPort);
                ready = true;
                host = false;
                System.out.println("Client Socket : OK");

                OutputStream flux = clientSocket.getOutputStream();
                OutputStreamWriter sortie = new OutputStreamWriter(flux);
                sortie.write("Nouveau !");
                sortie.flush();
            } catch (IOException ex) { System.err.println(ex.getMessage()); }
        }
    }

    @Override
    public void run() {
        while (true) {
            System.out.print("");
            if (ready) {
                // Serveur
                if (host) {
                    try {
                        Socket socket = serverSocket.accept();
                        InputStream flux = socket.getInputStream();
                        BufferedReader entree = new BufferedReader(new InputStreamReader(flux));
                        String message = entree.readLine();
                        System.out.println("Message : " + message);
                    } catch (IOException ex) { System.err.println(ex.getMessage()); }
                }

                // Client
                if (!host) {

                }
            }
        }
    }
}

J'ai donc le serveur et le client dans la même application, avec donc deux boutons : Un pour démarrer le serveur, l'autre pour s'y connecter.

Le problème, c'est que quand je lance l'application deux fois (je dit "Application" mais je parle là d'une version Linux), une fois pour le serveur et une fois pour le client, et que je me connecte via le client, le serveur ne reçois le message que lorsque le client ferme le programme…

Du coup, je comprend plus grand chose maintenant. :p

Quelqu'un pour m'aider ?

Merci ! :)

Édité par FougereBle

Essaye de mettre une valeur plus grande pour le port (50 800 par exemple).On sait jamais ^^
PS : Je te conseille de séparer ta partie client et serveur en 2 applications différentes car ici tu vas utiliser 2 fois le même port lorsque tu démarres deux fois l'application ,je pense que ton problème vient de là .

Édité par Octodex

+0 -1
Auteur du sujet

Merci pour ton message, mais cela ne change rien. :( D'autres idées ?

Edit: Je viens de voir ton Edit. Je test avec deux ports et je vous tiens au courant !

Edit 2 : Quand je met un port différent pour la partie Client, j'ai le message "Connexion refusée".

1
2
3
private final static int clientPort = 2501;
// ...
clientSocket = new Socket(serverIp, clientPort);

Édité par FougereBle

Essaye de mettre une valeur plus grande pour le port (50 800 par exemple).On sait jamais ^^

Octodex

S'il finit bien par recevoir le message, le problème n'est probablement pas là.

PS : Je te conseille de séparer ta partie client et serveur en 2 applications différentes car ici tu vas utiliser 2 fois le même port lorsque tu démarres deux fois l'application ,je pense que ton problème vient de là .

Octodex

Je ne pense pas, le port est utilisé une fois pour la connexion client, une fois pour le serveur. Il faut évidemment que ce soit le même pour les deux.

@FougereBle : As-tu volontairement caché la partie client ? Qui sait, le problème vient peut-être de là.

HS: Pour l'adresse du serveur, tu peux simplement mettre "localhost" ou "127.0.0.1", qui correspondront toujours à la machine locale.

Édité par Olybri

+1 -0

Essaye de mettre une valeur plus grande pour le port (50 800 par exemple).On sait jamais ^^

Non, sinon il aurait une erreur comme quoi le VM ne peux pas ouvrir ce port.

PS : Je te conseille de séparer ta partie client et serveur en 2 applications différentes car ici tu vas utiliser 2 fois le même port lorsque tu démarres deux fois l'application ,je pense que ton problème vient de là .

Ils sont sensé communiquer par le saint-esprit ensuite ? Ils doivent bien avoir le même port (Client et serveur) afin de pouvoir communiquer entre eux.

Sinon, je suis d'avis qu'il est conseiller de séparer le client du serveur.

Sinon je vais essayer ton code, car rien ne me saute aux yeux la.

+0 -0

Cette réponse a aidé l'auteur du sujet

Bon chez moi ça marche si j'utilise une autre méthode (celle que j'ai appris).

en modifiant ces lignes:

1
2
BufferedReader entree = new BufferedReader(new InputStreamReader(flux));
String message = entree.readLine();

par

1
2
DataInputStream in = new DataInputStream(socket.getInputStream());
String message = in.readUTF();

et

1
2
3
4
OutputStream flux = clientSocket.getOutputStream();
OutputStreamWriter sortie = new OutputStreamWriter(flux);
sortie.write("Nouveau !");
sortie.flush();

par

1
2
3
4
5
6
7
try {
    OutputStream outToServer = clientSocket.getOutputStream();
    DataOutputStream out = new DataOutputStream(outToServer);
    out.writeUTF("Un super messgae =D");
} catch (IOException e1) {
    e1.printStackTrace();
}

Et je crois que c'est tout ce que j'ai modifié (Par rapport à ton code original), si ça ne fonctionne pas dit le mois, que te créerai un petit gist.

WinXaito

+1 -0

Ils sont sensé communiquer par le saint-esprit ensuite ? Ils doivent bien avoir le même port (Client et serveur) afin de pouvoir communiquer entre eux.

Comme son serveur et son client sont contenus dans la même application s'il démarre deux application il y aura 2 serveurs connectés sur le même port.Sauf que je n'avais pas vu qu'il avait créé un bouton pour démarrer le serveur,je pensait que son serveur démarrait au même au moment qu'au lancement de l'application.

+0 -0

La partie client ne contient rien (si tu parles du code suivant). […]

FougereBle

Ah oui, je n'ai pas vu que la connexion côté client avait lieu directement dans la fonction actionPerformed. ^^

Bref, j'ai testé ton code, et ce n'est effectivement qu'avec les modifications de WinXaito que cela fonctionne chez moi.

+0 -0

Ils sont sensé communiquer par le saint-esprit ensuite ? Ils doivent bien avoir le même port (Client et serveur) afin de pouvoir communiquer entre eux.

Comme son serveur et son client sont contenus dans la même application s'il démarre deux application il y aura 2 serveurs connectés sur le même port.Sauf que je n'avais pas vu qu'il avait créé un bouton pour démarrer le serveur,je pensait que son serveur démarrait au même au moment qu'au lancement de l'application.

Je disais ça en rigolant, autant pour moi si ce n'était pas assez clair, ce n'était de loin pas une remarque ou insulte :)

+0 -0
Auteur du sujet

Merci WinXaito ! :) Ca fonctionne bien maintenant !

En fait je faisais comme ça car c'est comme ceci que c'est écrit dans mon livre. Après, ce livre est pour (je cite) "Java 5 et 6". Peut être donc que ce livre n'est plus à jour ?

Par contre… il y à un truc que je ne comprend vraiment pas !

Si vous regardez bien mon premier code, il y à un "System.out.print("")" à la ligne 66. Le truc, c'est que si je l'enlève, plus rien ne fonctionne (je n'ai plus le message "Message : Nouveau" qui viens du client). Alors que si je le laisse, et bien tout refonctionne… Etrange, non ?

Si vous regardez bien mon premier code, il y à un "System.out.print("")" à la ligne 66. Le truc, c'est que si je l'enlève, plus rien ne fonctionne (je n'ai plus le message "Message : Nouveau" qui viens du client). Alors que si je le laisse, et bien tout refonctionne… Etrange, non ?

Je vais regarder ça car c'est vraiment étrange

+1 -0
Auteur du sujet

Par contre, maintenant je bloque pour recevoir un tableau de byte avec le "DataInputStream". Malgré mes recherches, je n'ai pas trouvé. :(

Edit : Oui, c'est vraiment très étrange le System.out.print("") obligatoire !

Édité par FougereBle

Auteur du sujet

Héhé, justement, c'est ce que j'essaye de faire. :p

J'ai donc cette classe :

1
2
3
4
5
6
public class ServClient implements Serializable {

    public String ip = "";
    public int port;
    public int id = 0;
}

Et ce code qui gère la (dé)sérialisation :

 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
public byte[] serializeObject(Object objectToSerialize) {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream os = new ObjectOutputStream(out);
            os.writeObject(objectToSerialize);

            return out.toByteArray();
        } catch (IOException ex) {
            Logger.getLogger(GuiFrame.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public Object deserializeObject(byte[] objectToDeserialize) {
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(objectToDeserialize);
            ObjectInputStream is = new ObjectInputStream(in);
            return is.readObject();
        } catch (IOException ex) {
            Logger.getLogger(GuiFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(GuiFrame.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

Plus ce code côté client :

1
2
3
4
5
6
7
ServClient c = new ServClient();
c.ip = "test";
c.port = 123;
c.id = 42;

DataOutputStream sortie = new DataOutputStream(clientSocket.getOutputStream());
sortie.write(serializeObject(c));

Et enfin, ce code côté serveur :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
byte[] datas = new byte[entree.available()];
entree.read(datas);

ServClient c = (ServClient) deserializeObject(datas);

if (c != null) {
    System.out.println("Message : " + c.ip);
} else {
    System.out.println("Message : Null");
}

Problème : J'ai l'erreur suivante :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
janv. 18, 2016 9:51:18 PM castle.goblins.GuiFrame deserializeObject
GRAVE: null
java.io.EOFException
    at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2335)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2804)
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
    at castle.goblins.GuiFrame.deserializeObject(GuiFrame.java:141)
    at castle.goblins.GuiFrame.run(GuiFrame.java:106)
    at java.lang.Thread.run(Thread.java:745)

Message : Null

Édité par FougereBle

Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte