Bonjour tout le monde,
j'ai développé un serveur de chat en java.
Le serveur reçoit soit un identifiant de salon (exemple: #a184b3) si on est client, et si on envoie un message à tout les clients on envoie l'identifiant du salon + l'identifiant du message (exemple: a184b3;f548d63e2 ).

Le problème vient de la liste des clients, ils sont une date d'expiration pour ne pas accumuler, donc il y a un thread qui tourne et check toutes les 30 secondes, mais quand il supprime un client, il supprime toute la liste de client, je pense que c'est un problème de concurrence.

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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
import java.net.ServerSocket;
import java.net.Socket;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
 
public class TraficServer
{
  public static int port = 25210;
  public static int numClient = -2147483648;
  public static short expire = 300; // 5 minutes
 
  public static ConcurrentHashMap<String,List<GestionnaireClient>> listGC;
 
  public final static String MESSAGE_TIMEOUT = "!t";
 
  public static void main( String[] args )
  {
    if( args.length > 0 )
    {
      TraficServer.port = Integer.parseInt(args[0]);
 
      if( args.length > 1 ) {
        TraficServer.expire = (short)Math.abs(Integer.parseInt(args[1]));
      }
    }
    else {
      System.out.println("numéro de port : "+TraficServer.port);
    }
 
    new TraficServer();
  }
 
  public TraficServer()
  {
    // sera incrémenté à chaque fois qu'un client se connecte
    ServerSocket socketServeur;
    Socket socketAcceptee;
 
    listGC = new ConcurrentHashMap<String,List<GestionnaireClient>>();
 
    try
    {
      socketServeur = new ServerSocket(TraficServer.port);
      new checkCGExpire().start();
 
      while(true)
      {
        socketAcceptee = socketServeur.accept();
        if( TraficServer.numClient <= 2147483647 )
        {
          new Thread(new GestionnaireClient(socketAcceptee)).start();
        }
      }
    }
    catch( Throwable e )
    {
      System.out.println("Impossible de s'attacher à la socket "+TraficServer.port+" ou autre erreur Socket");
      System.exit(-1);
    }
  }
 
  /**
   * Ajoute un client
   */
  synchronized static void addInGC( String etat, GestionnaireClient gest )
  {
    List<GestionnaireClient> list;
 
    if( !listGC.containsKey(etat) ) {
      list = Collections.synchronizedList(new ArrayList<GestionnaireClient>());
      listGC.put( etat, list );
    }
    else {
      list = Collections.synchronizedList(listGC.get(etat));
    }
 
    list.add(gest);
    TraficServer.numClient++;
  }
 
  /**
   * Supprime un client
   */
  synchronized static void removeOfGC( String etat )
  {
    TraficServer.numClient -= listGC.get(etat).size();
    listGC.remove(etat);
  }
 
  public class GestionnaireClient implements Runnable
  {
    private Socket maSocket;
    private BufferedReader in;
    private PrintWriter out;
 
    public int expire;
 
    public GestionnaireClient( Socket pSocket )
    {
      this.maSocket = pSocket;
    }
 
    public void run()
    {
      boolean more = true;
      String line;
 
      try
      {
        in = new BufferedReader(new InputStreamReader(maSocket.getInputStream()));
        out = new PrintWriter(maSocket.getOutputStream(), true);
 
        while( more )
        {
          line = null;
 
          try
          {
            line = in.readLine();
            //System.out.println(line);
          }
          catch( IOException e )
          {
            //System.out.println("echec de la lecture");
          }
 
          // il n'y avait plus de données à lire, la connexion a
          if( line == null )
          {
            // vraissemblablement été fermée côté client
            more = false;
          }
          // si c'est un pour attendre un message
          else if( line.charAt(0) == '#' )
          {
            this.expire = (int) (System.currentTimeMillis() / 1000 + TraficServer.expire);
            TraficServer.addInGC( line.substring(1), this );
          }
          // si c'est pour envoyer un message à tout le monde
          else
          {
            this.envoieAll(line);
          }
        }
        this.maSocket.close();
 
        if( listGC.containsKey(line) ) {
          TraficServer.removeOfGC(etat);
        }
      }
      catch( IOException e )
      {
        //System.out.println("Erreur de transfert");
        System.exit(-1);
      }
      catch( Exception e )
      {
        //e.printStackTrace();
      }
    }
 
    synchronized public void envoieAll( String message )
    {
      Iterator<GestionnaireClient> i = null;
      String etat = message.substring(0,6);
      message = message.substring(7);
 
      if( listGC.containsKey(etat) )
      {
        i = listGC.get(etat).iterator();
 
        while( i.hasNext() )
        {
          GestionnaireClient gest = i.next();
          if( gest != this ) {
            gest.envoie(message);
          }
        }
      }
    }
 
    synchronized public void envoie( String s ) {
      out.println(s);
    }
  }
 
  public class checkCGExpire extends Thread
  {
    public void run()
    {
      while(true)
      {
        try {
          Thread.sleep(30000);
        }
        catch( InterruptedException e )
        {
          System.out.println("checkCGExpire is dead !");
          return;
        }
 
        this.cleanExpire(listGC.values().iterator());
      }
    }
 
    private void cleanExpire( Iterator<List<GestionnaireClient>> i )
    {
      int now = (int) (System.currentTimeMillis() / 1000);
      List<GestionnaireClient> n;
      Iterator<GestionnaireClient> y;
      GestionnaireClient gest;
 
      while( i.hasNext() )
      {
        n = Collections.synchronizedList(i.next());
        y = n.iterator();
        while( y.hasNext() )
        {
          gest = y.next();
          if( gest.expire < now )
          {
            gest.envoie(MESSAGE_TIMEOUT);
            TraficServer.numClient--;
            y.remove();
          }
        }
        if( n.isEmpty() ) {
          i.remove();
        }
      }
    }
  }
}
Voici tout le code, comme c'est pas un code compliqué je ne vois pas pourquoi je le cacherai
J'implore votre aide pour régler ce problème que je n'arrive pas à résoudre.