Visualizzazione dei risultati da 1 a 2 su 2

Discussione: Socket TCP

  1. #1

    Socket TCP

    Scrivere un programma client-server che usi i socket TCP tale che:
    Il server riceve sul socket, una coppia di interi
    .. E restituisce al client la somma..
    .. Che il client stampa a video.
    Modificare il programma in modo che il server accetti diverse coppie di interi dallo stesso client, che aspetta di ricevere il risultato di quella
    precedente prima di sottomettere la nuova coppia

    Io devo attuare la modifica del programma ma non riesco a farlo.

    Codice del client:
    codice:
    public class ClientEsercizio1 {    
    
        static Logger logger = Logger.getLogger("global");
        
        public static void main(String[] args) {
                          
            try {
                Socket socket = new Socket("localhost",9000);
                ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
                Scanner in = new Scanner(System.in);
                int[] xy = new int[2];
                while(true) {
                    xy[0] = in.nextInt();
                    xy[1] = in.nextInt();
                    outStream.writeObject(xy);
                    logger.info("Coppia inviata");
                    System.out.println(inStream.readObject());
                }
            } catch (EOFException e) {
                logger.severe("Problemi con la connessione:" + e.getMessage());
                e.printStackTrace();
            } catch (Throwable t) {
                logger.severe("Lanciata Throwable:" + t.getMessage());
                t.printStackTrace();
            }
        }
    
    
    }


    Codice del server:
    codice:
    public class ServerEsercizio1 {    
    
        static Logger logger = Logger.getLogger("global");
    
        public static void main(String[] args) {
            
            try {
                ServerSocket serverSocket = new ServerSocket(9000);
                logger.info("Socket instanziato, accetto connessioni...");
                Socket socket = serverSocket.accept();
                logger.info("Accettata una connessione... attendo comandi.");
                ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
                int[] xy;
                while(true) {
                    xy = (int[]) inStream.readObject();
                    logger.info("Ricevuta la coppia di interi");
                    int somma = xy[0] + xy[1];
                    outStream.writeObject(somma);
                }
            } catch (EOFException e) {
                logger.severe("Problemi con la connessione:" + e.getMessage());
                e.printStackTrace();
            } catch (Throwable t) {
                logger.severe("Lancatia Throwable:" + t.getMessage());
                t.printStackTrace();
            }
        }
    
    
    }
    Praticamente quando prendo in input da tastiera i 2 numeri, non mi dà il risultato ma continua ad aspettare input da tastiera all'infinito. Come posso risolvere? Grazie mille!
    Ultima modifica di Aleandro23; 15-10-2017 a 10:37

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Il codice non è proprio molto buono per diversi motivi. Ma andiamo con ordine. Innanzitutto quando si usano gli ObjectOutputStream/ObjectInputStream così e specialmente con i socket, la creazione di questi oggetti andrebbe fatta "incrociata". Se il server prima crea ObjectOutputStream e poi ObjectInputStream, il client dovrebbe invertire cioè prima creare ObjectInputStream e poi ObjectOutputStream.
    Questo perlomeno per evitare potenziali blocchi, perché il costruttore di ObjectOutputStream scrive già sullo stream come prima cosa il "header" della serializzazione e se dall'altra parte viene anche inviato lo stesso header, ci potrebbe essere un "deadlock".

    Come seconda cosa, quando si usano i socket e ci si vuole assicurare che l'invio dei dati avvenga davvero sul socket, è sempre bene fare un "flush" dopo la scrittura con il writeXXX o quello che usi.

    Come terza cosa (che non è facilmente evidente dal codice perché è un concetto della serializzazione!) c'è un problema legato a come la serializzazione gestisce gli oggetti. La serializzazione applica "di serie" un meccanismo di "caching" degli oggetti.
    Dato che nel client viene istanziato l'oggetto array (con new int[2]) una volta sola prima del ciclo, l'oggetto che invii è sempre lo stesso identico array a cui viene solo cambiato il contenuto. Ma il caching degli oggetti causa un problema. Al primo ciclo sarebbe tutto ok ma dal secondo ciclo in poi ti accorgeresti che con altri dati il risultato non è più quello che ti aspetti.
    Ultima modifica di andbin; 15-10-2017 a 11:17
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Ho incrociato la creazione degli stream, messo nel while l'istanziamento dell'array e fatto il flush ad ogni stampa; ma mi dà sempre lo stesso problema e non capisco il perchè.

    Codice server:
    codice:
    public class ServerEsercizio1Mod1 {    
        static Logger logger = Logger.getLogger("global");
        
        public static void main(String[] args) {
        
            try {
                ServerSocket serverSocket = new ServerSocket(9000);
                logger.info("Socket instanziato, accetto connessioni...");
                Socket socket = serverSocket.accept();
                logger.info("Accettata una connessione... attendo comandi.");
                ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
                int[] xy;
                while(true) {
                    xy = (int[]) inStream.readObject();
                    logger.info("Ricevuta la coppia di interi");
                    int somma = xy[0] + xy[1];
                    outStream.writeObject(somma);
                    outStream.flush();
                }
            } catch (EOFException e) {
                logger.severe("Problemi con la connessione:" + e.getMessage());
                e.printStackTrace();
            } catch (Throwable t) {
                logger.severe("Lancatia Throwable:" + t.getMessage());
                t.printStackTrace();
            }
        }
    
    
    }
    Codice client:
    codice:
    public class ClientEsercizio1 {    
        static Logger logger = Logger.getLogger("global");
        
        public static void main(String[] args) {
        
            try {
                Socket socket = new Socket("localhost",9000);
                ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
                ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
                Scanner in = new Scanner(System.in);
                while(true) {
                    int[] xy = new int[2];
                    xy[0] = in.nextInt();
                    xy[1] = in.nextInt();
                    outStream.writeObject(xy);
                    outStream.flush();
                    System.out.println(inStream.readObject());
                }
            } catch (EOFException e) {
                logger.severe("Problemi con la connessione:" + e.getMessage());
                e.printStackTrace();
            } catch (Throwable t) {
                logger.severe("Lanciata Throwable:" + t.getMessage());
                t.printStackTrace();
            }
        }
    
    
    }

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.