|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
[JAVA] GUI per Server Multithread
Ciao!
ho finalmente ultimato il mio server FTP multithread. Adesso è arrivata l'ora di "agganciare" ad esso la GUI. Non so come risolvere un problema di fondo. La gui presenta un bottone per la connessione e un bottone per la disconnessione. Come tutti sanno il lato server ha la struttura: Codice:
ServerSocket server = new ServerSocket(serverPort);
Socket welcomeSocket;
while(true){
welcomeSocket = server.accept();
..... // start del thread...
}
Il problema è che quando la gui richiama il metodo per la connessione, poi il programma si alluppa nel ciclo sopra riportato, impallando quindi anche la GUI. Non so come fare per "separare" i due processi... La gui si deve limitare a mettere in ascolto il server, e non deve aspettare che la classe contenente il ciclo appena scritto sopra termini, poichè attenderebbe inutilmente. Come posso fare? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Metti il ciclo di accept in un altro thread che fa da Boss, in una configurazione Boss-Worker. I Worker sono i thread che si occupano delle connessioni, il Boss si occupa di fare l'accept e smistare il lavoro.
Un'altra soluzione (che puo' essere usata assieme a questa che ti ho detto) e' usare socket "non bloccanti". Invece di bloccare l'esecuzione sull'accept, fai un "polling" sul socket, chiedendo ad ogni ciclo se e' disponibile una connessione, se lo e' crei un thread, altrimenti ripeti il ciclo in una forma di questo tipo (pseudo codice): Codice:
while (!QuitServer())
{
if (IsConnectionAvailable())
{
thread = CreateThread();
thread.HandleConnection();
}
ReleaseCPUToAnotherThread();
}
WaitForAllConnectionsToFinish();
La GUI puo' lanciare il thread del server e impostare una flag testata da QuitServer() quando il thread del server deve fermarsi.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
MMh... benone..
innanzitutto ti ringrazio per avermi risposto, e soprattutto in modo così dettagliato. Premetto che non ho mai sentito parlare di questa tecnica Boss-Worker, ne tantomeno ho mai sentito parlare di Socket non bloccanti. Dovrò quindi mettermi a studiare tali sistemi per poi apportare le dovute modifiche. Ti farò sapere... grazie ancora. |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Boss-Worker non e' nulla di trascendentale, e' quello che hai gia' fatto. Un thread si occupa solo di smistare il lavoro, nel tuo caso il thread principale, ma ne puoi creare un altro, e si chiama Boss. I thread creati che svolgono il lavoro vero e proprio si chiamano Worker. Quando finiscono il lavoro terminano o vanno in Sleep aspettando di vedersi assegnato del nuovo lavoro da svolgere dal Boss. Qui trovi del codice in Java per creare un server non bloccante: http://www.onjava.com/pub/a/onjava/2...io.html?page=2 E' un po' complesso, devo dire che in C# e' decisamente piu' semplice.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Apr 2005
Messaggi: 224
|
Ma in Java non c'è qualcosa di di simile alla "select" delle socket di Berkeley ?
E' usata per fare server del tipo "concorrente singolo-processo" , poteva essere comoda in questo caso... |
|
|
|
|
|
#6 | |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
|
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Dunque... nel frattempo ho trovato questo sistema:
Codice:
onlineButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
new Thread("Server starter") {
public void run() {
try{
FTPServerMultiThread.connect();
}catch (Exception ex){}
}
}.start();
onlineButton.setEnabled(false);
offlineButton.setEnabled(true);
}
});
Ho fatto la stessa cosa per il bottone offlineButton, ma ovviamente, la connessione non viene interrotta poichè i due thread non sono "comunicanti". Quindi ora mi rimarrebbe il problema della disconnessione. Per quanto riguarda i socket non bloccanti, non ha importanza, sto facendo un progetto per l'università, e devo usare quello che mi hanno insegnato. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Penso di aver risolto inserendo un
Thread.yield() dopo lo start(). ora funziona tutto; PORCA MISERIA ora invece non funziona proprio una mazza!!!!! prima andava! Ultima modifica di fbcyborg : 24-07-2005 alle 18:17. |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Dunque:
il mio software a grandi linee è così strutturato: public class Server{ ____private ServerSocket server ____public static void connect() throws IOException{ ________server = new ServerSocket(21); ________Socket connectionSocket; ________while(true){ ____________connectionSocket = server.accept(); ____________new ClientHandler(connectionSocket).start(); ________} ____} ____publi c static void offline() throws IOException{ ________server.close(); ____} } // Classe principale dell'applicazione: public class ClientHandler extends Thread{ ____private Socket connectionSocket; ____public ClientHandler(Socket clientSocket){ ________connectionSocket = clientSocket; ____} ____public void run(){ ________/* quì ci sono tutti i vari cicli while _________* che servono a chiamare le varie funzioni _________* del programma */ ____} ____public void doPut(){} ____public void doGet(){} ____//ecc.... } // Parte grafica: public class GUIServer extends JFrame{ ____public GUIServer(); ____public static void main(String[] args); ____private void initialize(); ____private void getOnlineButton{ ________// vari metodi x inizializzare ____onlineButton.addActionListener(new ____java.awt.event.ActionListener() { ________public void actionPerformed(java.awt.event.ActionEvent e) { ____________new Thread("Server starter") { ________________public void run() { ____________________try{ ________________FTPServerMultiThread.connect(); ____________________}catch (Exception ex){} ________________} ____________}.start(); /*ho provato a mettere uno stop() (deprecato) o uno yield() da queste parti ma non funzona bene. ____________onlineButton.setEnabled(false); ____________offlineButton.se tEnabled(true); ________} ____}); ____} } IDEM per l'offline Button, duale all'online Button. Questo è quanto, spero sia sufficiente per meglio chiarire la situazione Ultima modifica di fbcyborg : 24-07-2005 alle 20:21. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Feb 2001
Messaggi: 824
|
scusa, sta preparando l'esame di sistemi operativi 2 con crescenzi?:-D
__________________
Il Poeta assomiglia a questo principe // Dei nembi, che frequenta la tempesta // E ride dell'arciere; a lui, esiliato // Sulla terra, fra gli schiamazzi, le ali // Da gigante impediscono il cammino. (Baudelaire - l'albatro) |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
NO! magari fossero queste le cose x sistemi operativi 2!!!!!
cmq crescenzi non lo conosco... io sto alla sapienza. e tu? Ultima modifica di fbcyborg : 24-07-2005 alle 22:54. |
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Per fek:
Quote:
|
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Hai il ciclo di accept del server nel main. Ti serve spostarlo in un alro thread. Quindi?
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
il primo pensiero che mi viene in mente se mi dici così.... è quello di fare un extends Thread per la classe Server e mettere il while nel metodo run().
ma sinceramente sono andato un po' nel pallone... sarà il caldo, la voglia di mare, ma non saprei proprio... .. ma poi per chiudere il ServerSocket? oppure mettere ciò che sta nel main nella classe della GUI? mi sembra di averci provato.. forse ho sbagliato qualcosa |
|
|
|
|
|
#15 | |||
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Quote:
Un problema per volta. Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|||
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Ok, ho provato... però sulla gui succede questo:
alla pressione di un bottone per andare online, viene avviato il thread, che esegue il metodo run(). In questo metodo c'è il while true per accettare le connessioni. Ora però, non riesco a stoppare il thread(questo è l'unico modo che mi è venuto in mente per chiudere il ServerSocket) perchè non so come "acchiapparlo". Non ho un thread id come in C che posso decidere di terminare a mio piacimento... o almeno non ci riesco. il metodo offline() l'ho commentato.... ho provato anche con la funzione Thread.currentThread(), ma non mi fa fa re lo stop() (tra l'altro deprecato) di quel thread. Rimane quindi il solito problema della connessione aperta. |
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
dunque... questa è la mia classe Boss
Codice:
public class FTPServerMultiThread extends Thread{
private ServerSocket mainSocket = null;
public FTPServerMultiThread(){
}
public void run(){
int serverPort = 21; // FTP server port
Socket connectionSocket;
String[][] userList = null;
String slash = System.getProperty("file.separator");
String root = System.getProperty("user.dir") + slash +"FileSystem";
try{
mainSocket = new ServerSocket(serverPort);
System.out.println("Server in ascolto sulla porta "+ serverPort +"...");
while(true){
connectionSocket = mainSocket.accept();
if (connectionSocket.isConnected()){
new ClientHandler(connectionSocket).start();
}
else Thread.yield();
}
}catch (IOException ex){}
}
/*public void offline() throws IOException{
mainSocket.close();
}*/
}
Se io volessi chiudere il server brutalmente, i client verrebbero disconnessi dando un errore all'utente.. |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Guarda:
Codice:
while (!QuitServer())
{
if (IsConnectionAvailable())
{
thread = CreateThread();
thread.HandleConnection();
}
ReleaseCPUToAnotherThread();
}
WaitForAllConnectionsToFinish();
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
il fatto del quitServer().
questo significa che devo implementare un nuovo metodo? analogo a offline() ? alla fine siamo sempre lì.. a me servirebbe tipo un SEGNALE che inviato a quel thread, termini... dici così? Codice:
public class FTPServerMultiThread extends Thread{
private ServerSocket mainSocket = null;
private boolean status = false;
public FTPServerMultiThread(){
}
public void run(){
int serverPort = 21; // FTP server port
Socket connectionSocket;
String[][] userList = null;
String slash = System.getProperty("file.separator");
String root = System.getProperty("user.dir") + slash +"FileSystem";
try{
mainSocket = new ServerSocket(serverPort);
status = true;
System.out.println("Server in ascolto sulla porta "+ serverPort +"...");
while(status){
connectionSocket = mainSocket.accept();
if (connectionSocket.isConnected()){
new ClientHandler(connectionSocket).start();
}
}
mainSocket.close();
}catch (IOException ex){}
}
public void offline() throws IOException{
status = false;
}
}
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:25.




















