Bonjour,

Je suis entrain de faire un jeu de carte online, c'est la première fois que je me lance dans un programme en réseau avec multithread un peu plus pousser que de simple chat, etc...

Il y a une application client et une serveur.

Voici ce que je veux faire en ce moment :
1) Le client entre son login
2) La connection au serveur s'établie
3) Le client envoie les données pour le login et le mot de passe
4) Le serveur reçoit et va checker dans la base de donnée
5) Si c'est bon il renvoie une confirmation positive au client sinon un rejet.
6) Le client reçoit et affiche un message.

De 1 à 4 tout va bien, mais quand le server doit aller envoyer la donnée de confirmation quelque chose de spécial se passe : le serveur recoit une nouvelle connexion de mon client et puisque je lui fait checker s'il est pas déjà connecté il va tout rejetter, ce qu'il ne devrait pas faire. Et ensuite il crash (le serveur)
Citation Envoyé par Console serveur
New connection !
Number of thread : 2
Packet receive : uno.Data@89ae9e
class uno.Player
New connection !
Server has refused connection : 192.168.1.34 - Already connect
Exception in thread "Thread-0" java.util.ConcurrentModificationException
It didn't work! - Software caused connection abort: socket write error
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at unoserver.Server$DaemonThread.run(Server.java:65)
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1838)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1747)
at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1249)
at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1203)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1387)
thread interrupted
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1538)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:329)
at unoserver.Network.writeObject(Network.java:24)
at unoserver.cmdToServer.acceptedConnect(cmdToServer.java:183)
at unoserver.cmdToServer.getPlayerConnectServer(cmdToServer.java:172)
at unoserver.cmdToServer.analyse(cmdToServer.java:75)
at unoserver.Server$ServerData.run(Server.java:109)
at java.lang.Thread.run(Thread.java:619)
J'ai trouvé que cette erreur arrive si l'on n'utilise pas d'iterator pour parcourir une liste, donc c'est ce que j'ai fait mais l'erreur persiste.

J'ai cherché pourquoi le serveur croit recevoir une nouvelle demande de connexion et je n'ai pas trouvé pourquoi. Le client ne se connecte qu'une seul fois je l'ai bien vérifié.

Voici le code du serveur où il gère les threads :

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
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package unoserver;
 
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
 *
 * @author rxp
 */
public class Server {
 
    // list of the inetaddress connected
private List <InetAddress> address;
// port of teh application
private int port = 1991;
 
    public Server() throws IOException{
        //init
        address = new ArrayList<InetAddress>();
        Thread t = new DaemonThread();
 
  }
 
    class DaemonThread extends Thread{
        public DaemonThread(){
            //start the main thread
        start();
        }
 
        @Override
        public void run(){
 
        Socket skt = null;
        ServerSocket srvr = null;
            try {
                //open the port
                srvr = new ServerSocket(port);
            } catch (IOException ex) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }
 
        while(true){
             try{
                 //accept the connections
                 skt = srvr.accept();
                 System.out.print("New connection ! \n");
                 //create an iterator of address
                 Iterator it = address.iterator();
                 //check in address if the client is already connected
                 while(it.hasNext()){
                     InetAddress add = (InetAddress) it.next();
                     if(skt.getInetAddress().equals(add)){
                         System.out.print("Server has refused connection : "+add.getHostAddress()+" - Already connect \n");
                         closeConnection(skt, false);
                     }else{
                     }
                 }
                 //error
            }catch(IOException ioe){
                 System.out.print("It didn't work! - "+ioe.getMessage()+"\n");
                 ioe.printStackTrace();
                 closeConnection(skt, false);
            }
             //if no error :
                 // add the inetaddress to address
             address.add(skt.getInetAddress());
                // create the thread
             Thread t = new Thread(new ServerData(skt));
                // start the thread
             t.start();
        }
 
        }
    }
 
 
  class ServerData implements Runnable{
      private Socket skt;
      Network network;
      cmdToServer cts = new cmdToServer();
      public ServerData(Socket skt){
          //init
          this.skt = skt;
          network = new Network();
          // number of thread
          System.out.println("Number of thread : "+Thread.activeCount());
      }
 
      public void run(){
 
      try{
                try {
                    try {
                        //analyse the packet juste receive
                        cts.analyse((Object) network.readObject(skt), skt.getInetAddress());
                    } catch (SQLException ex) {
                        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (NoSuchAlgorithmException ex) {
                        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
                }
         }catch(IOException ioe){
             //if error :
             //close the connection
            System.out.print("It didn't work! - "+ioe.getMessage()+"\n");
            ioe.printStackTrace();
                closeConnection(skt, true);
         }
      }
 
  }
 
  public void closeConnection(Socket skt, boolean thread){
    try {
        //remove address from address
            address.remove(skt.getInetAddress());
            //close the socket
            skt.close();
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
        if(thread == true){
            //if want to :
            System.out.println("thread interrupted");
            //kill the thread
            Thread.currentThread().interrupt();
        }
 
  }
La ligne erronée est sois-disant celle-ci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
InetAddress add = (InetAddress) it.next();