Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1

    Comunicazione client-server non funzionante

    Salve. Sto creando una chat client-server che per ora funziona solo in locale. Il problema è che all'atto della connessione del client al server, il client non riceve messaggi dal server. Il server sembra rilevare correttamente la connessione del client. Il codice non è breve, provo a mettere le parti più rilevanti (che comunque potrebbero essere utili a qualcuno).

    Server

    codice:
    public class Server implements Runnable {
    
    
        private List<ServerClient> clients = new ArrayList<ServerClient>();
        
        private DatagramSocket socket;
        private int port;
        private boolean running = false;
        private Thread run, manage, send, receive;
        
        public Server(int port) {
            this.port = port;
            try {
                socket = new DatagramSocket(port);
            } catch (SocketException e) {
                e.printStackTrace();
                return;
            }
            run = new Thread(this, "Server");
            run.start();
        }
        
        public void run() {
            running = true;
            System.out.println("Server started on port " + port);
            manageClients();
            receive();
        }
        
        private void manageClients() {
            manage = new Thread("Manage") {
                public void run() {
                    while(running) {
                        //niente per adesso
                    }
                }
            };
            manage.start();
        }
        
        private void receive() {
            receive = new Thread("Receive") {
                public void run() {
                    while(running) {
                        byte[] data = new byte[1024];
                        DatagramPacket packet = new DatagramPacket(data, data.length);
                        try {
                            socket.receive(packet);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        System.out.println("Ricevuto pacchetto da: " + packet.getAddress().toString() + " , " + packet.getPort());
                        process(packet);
                    }
                }
            };
            receive.start();
        }
        
        private void process(DatagramPacket packet) {
            String string = new String(packet.getData());
            if(string.startsWith("/c/")) {
                //UUID id = UUID.randomUUID();
                int id = UniqueIdentifier.getIdentifier();
                clients.add(new ServerClient(string.substring(3, string.length()), packet.getAddress(), 
                        packet.getPort(), UniqueIdentifier.getIdentifier()));
                System.out.println(string.substring(3, string.length()));
                String ID = "/c/" + id;
                send(ID, packet.getAddress(), packet.getPort());
            } else if(string.startsWith("/m/")){
                sendToAll(string);
            } else if(string.startsWith("/d/")) {
                String id = string.split("/d/|/e/")[1];
                disconnect(Integer.parseInt(id), true);
            }        
            else {
                System.out.println(string);
            }
        }
        
        private void disconnect(int id, boolean status) {
            ServerClient c = null;
            for(int i = 0; i < clients.size(); i++) {
                if(clients.get(i).getID() == id) {
                    c = clients.get(i);
                    clients.remove(i);
                    break;
                }
            }
            String message = "";
            if(status) {
                message = "Client " + c.getName() + " (" + c.getID() + ") @" 
                        +c.getAddress().toString() + ":" + c.getPort() + " disconnected";
            } else {
                message = "Client " + c.getName() + " (" + c.getID() + ") @" 
                        +c.getAddress().toString() + ":" + c.getPort() + " timed out";
            }
            System.out.println(message);
        }
        
        private void sendToAll(String message) {
            for(int i = 0; i < clients.size(); i++) {
                ServerClient client = clients.get(i);
                send(message.getBytes(), client.getAddress(), client.getPort());
            }
        }
        
        private void send(String message, InetAddress address, int port) {
            message += "/e/"; //carattere di terminazione
            send(message.getBytes(),address,port);
        }
        
        private void send(final byte[] data, final InetAddress address, final int port) {
            send = new Thread("Send") {
                public void run() {
                    DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                    System.out.println("Server is sending a packet to: " + 
                            packet.getAddress() + " , " + packet.getPort());
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            send.start();
        }
    }
    ClientWindow

    codice:
    public class ClientWindow extends JFrame implements Runnable {
        
        private static final long serialVersionUID = 1L;
        
        private JPanel contentPane;
        private JTextField txtMessage;
        private JTextArea history;
        
        private Client client;
        private Thread listen, run;
        private boolean running = false;
        
        public ClientWindow(String name, String address, int port) {
            setTitle("Client");
            client = new Client(name, address, port);
            boolean connect = client.openConnection(address);
            if(!connect) {
                System.err.println("Connection Failed");
                console("Connection Failed");
            }
            createUI();
            console("Attempting a connection to " + address + ":" + port + ", user: " + name);
            String connection = "/c/" + name;
            client.send(connection.getBytes());
            running = true;
            run = new Thread("Running Thread");
            run.start();
        }
    
    
        private void createUI() {
            //ho tolto per abbreviare
        }
        
        private void console(String message) {
            history.append(message + "\n\r");
            history.setCaretPosition(history.getDocument().getLength());
        }
        
        public void run() {
            System.out.println("Client run() method");
            listen();
        }
        
        private void send(String message, boolean text) {
            if(message.equals("")) return;
            if(text) {
                message = client.getName() + ": " + message;
                message = "/m/" + message;
            }
            client.send(message.getBytes());
            txtMessage.setText("");
        }
        
        private void listen() {
            System.out.println("Client listen() method");
            listen = new Thread("Listen") {
                public void run() {
                    while(running) {
                        String message = client.receive();
                        if(message.startsWith("/c/")) {
                            client.setID(Integer.parseInt(message.split("/c/|/e/")[1]));
                            console("Successfully connected to server. ID: " + client.getID()); 
                        } else if(message.startsWith("/m/")) {
                            String text = message.split("/m/|/e/")[1];
                            console(text);
                        }
                    }
                }
            };
            listen.start();
        }
    }

    Client

    codice:
    public class Client {    
        
        private String name, address;
        private int port;    
        private DatagramSocket socket; //Protocollo UDP
        private InetAddress ip;
        
        private Thread send;
        
        private int ID = -1;
        
        public Client(String name, String address, int port) {
            this.name = name;
            this.address = address;
            this.port = port;
        }
        
        public String getName() {
            return name;
        }
        
        public String getAddress() {
            return address;
        }
        
        public int getPort() {
            return port;
        }
    
    
        public boolean openConnection(String address) {
            try {
                socket = new DatagramSocket();
                ip = InetAddress.getByName(address);
            } catch (UnknownHostException e) {
                e.printStackTrace();
                return false;
            } catch (SocketException e) {
                e.printStackTrace();
                return false;
            }
            System.out.println("Client connection ok");
            return true;
        }
        
        public String receive() {
            byte[] data = new byte[1024]; //buffer dove riceviamo i dati
            DatagramPacket packet = new DatagramPacket(data, data.length); //pacchetti UDP
            System.out.println("Client is receiveing a packet from: " + packet.getAddress() + " , " + packet.getPort());
            try {
                socket.receive(packet); //riceviamo i pacchetti dal network
            } catch (IOException e) {
                e.printStackTrace();
            }
            String message = new String(packet.getData());
            return message;
        }
        
        public void send(final byte[] data) {
            send = new Thread("Send") {
                public void run() {
                    DatagramPacket packet = new DatagramPacket(data, data.length, ip, port);
                    System.out.println("Client is sending a packet to: " + packet.getAddress() + " , " + packet.getPort());
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            send.start();
        }
        
        public void close() {
            new Thread() {
                public void run() {
                    synchronized(socket) {
                        socket.close();
                    }
                }
            }.start();
        }
    
    
        public void setID(int ID) {
            this.ID = ID;
        }
        
        public int getID() {
            return ID;
        }
    }
    In particolare la receive() della classe Client e la listen() della classe ClientWindow sembrano non funzionare.

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    339
    Hai messo un bel pò di codice...
    Cerca di essere il più conciso possibile altrimenti dubito che qualcuno ti risponderà (capitato anche a me).

    P.S. : Non è che per caso stai facendo Reti di Calcolatori all'Unical?

  3. #3
    No, comunque ho specificato qual è il problema. Il client non riceve nulla. Le stampe che ho messo in listen() e receive() non vengono eseguite. Il server sembra funzionare correttamente. Se dal client io digito qualcosa ed invio, il server risponde inviando il messaggio a tutti gli eventuali client (e lo fa!) ma i client non ricevono niente e nella console non compare nulla.

    A dire il vero anche all'atto della connessione del client con il server dovrebbe comparire un messaggio su console. Il server capisce che un client si è connesso (infatti lato server eseguo correttamente delle stampe), risponde al client appena connesso che però non riceve niente.
    Ultima modifica di Javino89; 29-05-2014 a 17:21

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    339
    Anche io sto sbattendo la testa per vedere come riuscire a testare in locale...

    Cmq da quello che ho appreso fino ad ora posso dirti che devi utilizzare indirizzi del tuo pc ossia indirizzi localHost.

    Quando vai a creare un indirizzo metti :

    InetAddress address = InetAddress.getLocalHost();

  5. #5
    In realtà quando vado a fare il login (non ho messo la classe login) prima della connessione riempio 3 campi: nome, ip e porta.
    Il Server ascolta sulla porta 8192 quindi devo mettere questo numero, il nome può essere qualsiasi e come ip specifico "localhost".
    Tale stringa viene passata alla classe ClientWindow che crea e connette un Client con i dati passati nel login. Il metodo openConnection() sopra mostrato converte "localhost" in ip vero e proprio in questo modo:

    ip =InetAddress.getByName(address);



  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    339
    Quote Originariamente inviata da Javino89 Visualizza il messaggio
    Il metodo openConnection() sopra mostrato converte "localhost" in ip vero e proprio in questo modo:

    ip =InetAddress.getByName(address);


    Spiegati meglio. Converte "localHost" ? Cioè la stringa?

    Perchè non metti direttamente l'indirizzo di localhost ; 127.0.0.1

    ip = InetAddress.getByName("127.0.0.1");

  7. #7
    Perché gli viene passato dal login dove puoi mettere l'indirizzo ip che ti pare, in modo tale che si adatti a situazioni più generali.

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    339
    Quote Originariamente inviata da Javino89 Visualizza il messaggio
    Perché gli viene passato dal login dove puoi mettere l'indirizzo ip che ti pare, in modo tale che si adatti a situazioni più generali.
    Se vuoi testare in locale , non puoi mettere l'indirizzo ip che ti pare.


    Client e Server sono sulla stessa macchina .


    Per i test in locale si utilizza un indirizzo ip particolare . Da windows vista in poi è 127.0.0.1


    Se tu metti un indirizzo qualsiasi ad esempio 156.12.1.0 non potrà mai funzionare sulla stessa macchina

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    @Markus85: stai prendendo un piccolo abbaglio... Javino89 non sta passando un ip qualunque, sta dicendo che ha progettato l'applicazione in modo che in qualunque momento sia possibile specificare l'IP... per le prove in locale lui sta specificando correttamente "localhost" (che, tra l'altro, non è che da Win Vista in poi sia 127.0.0.1... è sempre stato così, fin da quando sono state inventate le reti)

    @Javino89:
    Io l'unico problema che vedo in quel codice è il modo in cui viene creata la DatagramSocket: non stai specificando il numero di porta, ma stai usando il costruttore senza parametri. Questo significa che la Socket verrà creata sul localhost, alla prima porta disponibile sul sistema (quindi, non necessariamente la 8192, anzi... proprio mai, se non sono occupate tutte le precedenti porte).


    codice:
    public boolean openConnection(String address) {
       try {
          socket = new DatagramSocket();  //<--- Manca la porta!
          ip = InetAddress.getByName(address);
       } catch (UnknownHostException e) {
          ...
    }

    Dovresti usare il costruttore che prende come parametro l'intero della porta.


    Ciao.
    Ultima modifica di LeleFT; 30-05-2014 a 13:35
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Edit... anch'io ho preso un abbaglio: quella era la classe client, non la server.

    Faccio delle prove, per capire cosa accade, che così, ad occhio, non vedo nulla.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

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 © 2025 vBulletin Solutions, Inc. All rights reserved.