Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2015
    Messaggi
    32

    [JAVA]Problema con un banale ServerUDP Multithread

    Salve a tutti , sto facendo un banalissimo test per scambio di messaggi tra un Server UDP e n Client UDP e il test ha funzionato benissimo. Nel momento in cui però voglio rendere il tutto Multithread ... non so come mai ma non funziona , o meglio l'esecuzione va, ma ricevo un mare di errori a run time.

    ClientUDP :
    codice:
    package client;
    
    import java.io.*;
    import java.net.*;
    
    
    public class ClientUDP {
    
    
        public static void main(String[] args) {
            try {
                
                //Invio Messaggio Al server
                DatagramSocket s = new DatagramSocket();
                System.out.println("[CLIENT] Invio messaggio al server");
                String msg  = new String("Ciao Server");
                DatagramPacket request = new DatagramPacket(msg.getBytes(),msg.getBytes().length,InetAddress.getLocalHost(),8000);
                Thread.sleep(5000);
                s.send(request);
                
                //Ricezione Risposta Server
                byte data[] = new byte[65508];
                DatagramPacket answer = new DatagramPacket(data,data.length);
                System.out.println("[CLIENT] in attesa di risposta dal server");
                s.receive(answer);
                String ans = new String(answer.getData(),0,answer.getLength());
                System.out.println("[CLIENT] risposta dal server ricevuta= "+ans);
                
                //chiusura socket
                s.close();
            }
            catch(IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    ServerUDP:
    codice:
    package server;
    
    import java.io.*;
    import java.net.*;
    
    
    public class ServerUDP {
        public static void main(String[] args) {
            while(true) {
                try {
                    DatagramSocket socket = new DatagramSocket(8000);
                    byte data[] = new byte[65508];
                    DatagramPacket listening = new DatagramPacket(data, data.length);
                    System.out.println("[Server] In attesa di pacchetto UDP...");
                    socket.receive(listening);
                    System.out.println("[Server] Istanzio un WorkerServerUDP");
                    WorkerServerUDP w = new WorkerServerUDP(listening);
                    w.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
    
            }
        }
    
    
    }
    WorkerServerUDP (il thread che dovrebbe eseguire le interazioni con il client ... il server dovrebbe solo fare listening e lasciare le varie interazioni ai threads) :
    codice:
    package server;
    
    import java.io.*;
    import java.net.*;
    
    
    public class WorkerServerUDP extends Thread{
        
        private DatagramPacket p;
    
    
        
        public WorkerServerUDP(DatagramPacket pkt) {
            p = pkt;
        }
        
        public void run() {
            try {
            //Istanzio una DatagramSocket per send/recieve
            DatagramSocket s = new DatagramSocket();
            
            //Lettura messaggio client 
            byte[] receivedData = p.getData();
            String msg = new String(receivedData,0,p.getLength());
            System.out.println("[Worker] Messaggio ricevuto dal client= "+msg);
            
            //Invio ack al client 
            String response = new String("ack");
            DatagramPacket risp = new DatagramPacket(response.getBytes(),response.getBytes().length,p.getAddress(),p.getPort());
            System.out.println("[Worker] Invio Risposta");
            s.send(risp);
            System.out.println("[Worker] Risposta inviata");
            
            //chiusura socket
            s.close();
            } 
            catch (IOException e) {
                
                e.printStackTrace();
            }
        }
    }

    Quello che succede avviando da cmd è :
    http://i64.tinypic.com/2egcwfl.png


    Se vedete la prima schermata a sinistra (il server) sebbene gli innumerevoli errori , procede fino alla fine e di fatti , nella schermata a destra , il client riceve anche l'ack mandatagli dal thread.

    Quindi l'esecuzione funziona ( di fatti ho fatto un copia incolla del codice che prima era tutto in ServerUDP.java nella run di WorkerServerUDP.java ) solo che quando il codice della run era in ServerUDP.java tutto funzionava senza errori , ora che è in WorkerServerUDP.java funziona ma dà una caterva di errori... Sapete spiegarmi perché e come risolvere ? Grazie In Anticipo

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Warioss Visualizza il messaggio
    ServerUDP:
    codice:
            while(true) {
                // ......
                    DatagramSocket socket = new DatagramSocket(8000);
            }
    Dato che nel ciclo (potenzialmente "infinito" essendoci true) NON c'è il close() del socket, ad ogni ciclo cerchi di creare un DatagramSocket bindato sulla porta locale 8000. Ovviamente lo puoi fare una volta sola. Dal secondo ciclo in poi ...... bam.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2015
    Messaggi
    32
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Dato che nel ciclo (potenzialmente "infinito" essendoci true) NON c'è il close() del socket, ad ogni ciclo cerchi di creare un DatagramSocket bindato sulla porta locale 8000. Ovviamente lo puoi fare una volta sola. Dal secondo ciclo in poi ...... bam.
    Sono stupido ahahah hai ragione, non ci avevo proprio pensato , grazie mille. Alla prossima

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da Warioss Visualizza il messaggio
    hai ragione, non ci avevo proprio pensato
    Comunque anche mettendo il close(), ad ogni ciclo crei e chiudi il DatagramSocket ... che non è il massimo. Basta crearlo una volta sola. E quindi si tratta di rimaneggiare meglio quella parte.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2015
    Messaggi
    32
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Comunque anche mettendo il close(), ad ogni ciclo crei e chiudi il DatagramSocket ... che non è il massimo. Basta crearlo una volta sola. E quindi si tratta di rimaneggiare meglio quella parte.
    Giusto , è un po' uno spreco fare così semplicemente con una close. Ho risolto creandomi una nuova classe SingletonPatternSocketUDP che sfrutta il design pattern singleton (in questo modo l'ho rimossa proprio la close() in ServerUDP ) :

    codice:
        
    public static synchronized  SingletonPatternSocketUDP getSocketUDP(int porta) {        
    if(istanza == null)
                istanza = new SingletonPatternSocketUDP (porta);
            return istanza;
        }
    e funziona benissimo , senza errori (se può servire pubblico tutto il codice della classe SingletonPatternSocketUDP e non solo il metodo getSocketUDP sopra-riportato)
    Ultima modifica di Warioss; 29-04-2018 a 16:17

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.