PDA

View Full Version : [JAVA] Socket multithread -- distinguere i client


ciccionamente90
06-06-2013, 14:00
Buongiorno. Sono alle prese col socket multithread.
Banalmente ho e.g. tre client che si connettono al server ed essi sono in grado d'inserire una stringa, la quale verrà salvata nella "logica" del server. Ogni client - inoltre - è in grado di leggere l'ultima stringa scritta dagli altri client.

Se e.g. io sono il client2 posso inserire una stringa e "contemporaneamente vedere la (ultima) stringa inserita dal client1 e quella inserita dal client3.

Il mio problema è che non riesco a distinguere da quale specifico client proviene una stringa -- in modo tale da salvarla in una variabile String dedicata appunto a tale client.
C'è quindi modo di distinguere i client (sul lato server)?

clockover
06-06-2013, 16:02
Buongiorno. Sono alle prese col socket multithread.
Banalmente ho e.g. tre client che si connettono al server ed essi sono in grado d'inserire una stringa, la quale verrà salvata nella "logica" del server. Ogni client - inoltre - è in grado di leggere l'ultima stringa scritta dagli altri client.

Se e.g. io sono il client2 posso inserire una stringa e "contemporaneamente vedere la (ultima) stringa inserita dal client1 e quella inserita dal client3.

Il mio problema è che non riesco a distinguere da quale specifico client proviene una stringa -- in modo tale da salvarla in una variabile String dedicata appunto a tale client.
C'è quindi modo di distinguere i client (sul lato server)?

Basta che il server ad ogni thread (e quindi ad ogni client) assegni (quindi gli passa come parametro) un identificativo univoco.

pabloski
06-06-2013, 18:55
La connessione come funziona? I client si connettono più volte nel tempo? Oppure si apre la connessione, si fanno le operazioni, si chiude e stop?

ciccionamente90
06-06-2013, 18:58
Sì, infatti poi ho risolto così. Speravo esistesse un modo più pulito.
In pratica nel server ho messso:
private static int contatore=1; //idClient

static void incrementaContatore(){
setContatore(getContatore()+1);

public static int getContatore() {
return contatore;
}

public static void setContatore(int contatore) {
MultiServer.contatore = contatore;
}

Mentre nel codice di generazione dei thread:
private static int identificatore;

public MultiServerThread(Socket socket, int idClient) {
super("MultiServerThread");
this.socket = socket;
MultiServerThread.setIdentificatore(idClient);
MultiServer.incrementaContatore();
}
public static int getIdentificatore() {
return identificatore;
}
public static void setIdentificatore(int identificatore) {
MultiServerThread.identificatore = identificatore;
}

La logica la chiamo in questo modo:
Protocol p = new Protocol(identificatore);
La quale implementa:
int id;

Protocol(int identificatore){
this.id=identificatore;
}
Così da poter effettuare una distinzione.

Una curiosità: in programmi più complessi l'unico modo per chiamare metodi del server tramite socket è quello di utilizzare codici univoci i quali vengono verificati tramite una serie di switch (serializzando i parametri da passare)? Oppure esiste un modo più elegante?

ciccionamente90
06-06-2013, 18:59
La connessione come funziona? I client si connettono più volte nel tempo? Oppure si apre la connessione, si fanno le operazioni, si chiude e stop?

I client possono connettersi in qualsiasi momento e la connessione rimane costantemente aperta.

banryu79
07-06-2013, 07:55
Ciao ciccionamente90, cosa succede se capita che due client diversi si connettono più o meno nello stesso momento?
Succede che potrebbe capitare che due thread client vengano creati con lo stesso id perchè l'accesso in lettura e scrittura al campo "contatore" non è sincronizzato tra i thread (data race).

Soluzione rapida?
Dichiara i metodi incrementaContatore getContatore setContatore col modificatore synchronized.

ciccionamente90
07-06-2013, 09:01
Grazie mille per la dritta. Sistemo asap. :)

EDIT

ciccionamente90
09-06-2013, 20:31
Ragazzi, avrei un'ultima domanda. In questo caso il server è "stupido", nel senso che esegue la stessa azione a prescindere dal client. Ma come posso fare per far si che il server invii una determinata informazione (e.g. un oggetto serializzato) ad uno specifico client?

i.e. ho i thread dei socket che rimangono costantemente aperti e vorrei che il server passi un messaggio ad uno solo di questi thread -- come se volessi implementare il gioco della "patata bollente": il server numera i thread da 1 a 5 e i client sanno di essere in cinque. Un client scrive un messaggio con un destinatario (un numero da 1 a 5). Il server lo recapita al destinatario e quest'ultimo esegue la stessa procedura.

Spero che mi possiate aiutare, grazie in anticipo.

Non m'interessa tanto l'implementazione del messaggio, bensì la procedura che attua il server per instradare - univocamente - il messaggio stesso.