Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    396

    leggere i messaggi da socket

    Ciao, ho un server socket che manda di continuo dei pacchetti verso un client.
    Adesso vorrei che oltre a mandare i pacchetti ricevesse quelli che il client gli scrive.

    Ecco il codice del server:
    codice:
    OutputStream s1out = cliente.getOutputStream();
    BufferedOutputStream bw = new BufferedOutputStream(s1out);
    while(!inattivo){
        bw.write((byte)packet.length);
        bw.write(packet);
        bw.flush();
    }
    Se aggiungo a questo codice il corrispondente codice per leggere i pacchetti
    codice:
    InputStream s1in = cliente.getInputStream();
    BufferedInputStream br = new BufferedInputStream(s1in);
    while(true){
    br.read(pak);
    System.out.print("Il pacchetto letto è:"+pak);
    }
    Posso leggere i pacchetti in ingresso?
    I pacchetti che leggo li memmorizza nella variabile "pak"?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: leggere i messaggi da socket

    Originariamente inviato da Salinas
    codice:
    br.read(pak);
    Posso leggere i pacchetti in ingresso?
    I pacchetti che leggo li memmorizza nella variabile "pak"?
    No, alt! Innanzitutto con una read() come quella, pak si presuppone che sia un array byte[] già istanziato di una certa dimensione. E la read legge N byte al massimo quanto la dimensione dell'array.

    E non ti basta. Perché il protocollo è ben chiaro vedendo la parte di invio che hai postato. C'è un byte iniziale che indica la dimensione del pacchetto. (ne avevamo già parlato in un'altra discussione, se ben ricordo!).

    Quindi prima leggi 1 byte, deduci la dimensione del pacchetto, quindi istanzi un array byte[] della giusta dimensione e alla fine fai una read tale per cui ti aspetti esattamente X bytes.

    Nota che come ho detto prima, le read() che ricevono un array leggono al massimo quella dimensione ma possono leggere di meno a seconda di cosa è arrivato (e che dipende da come è stato inviato). In linea generale dovresti fare, per sicurezza, un loop per assicurarti di leggere esattamente X bytes.
    Ma se non vuoi complicarti la vita, il BufferedInputStream incapsulalo in un DataInputStream, che ha un comodissimo readFully(byte[] b). Questo si blocca e ritorna solo quando ha letto esattamente X byte quanto la lunghezza dell'array.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    396
    Come faccio ad applicare la tua ultima soluzione in questo caso?
    Qui non utilizza buffer.
    Dovrebbe funzionare per leggere i pacchetti, vero?
    codice:
    protected byte[] readSourcePacket() throws IOException {
    	// Protocol is straightforward: 1 size byte, <n> data bytes
    	byte[] size = readN(1);
    
    	if (size[0] == 0)
    	    throw new IOException("0-byte packet");
    	byte[] read = readN(size[0] & 0xff);
    	//Dump.dump("reading", read);
    	return read;
        }
    
        protected byte[] readN(int n) throws IOException {
    	byte[] data = new byte[n];
    	int offset = 0;
    
    	// A timeout would be nice, but there's no obvious way to
    	// write it before java 1.4 (probably some trickery with
    	// a thread and closing the stream would do the trick, but...)
    	while (offset < n) {
    	  int count = is.read(data, offset, n - offset);
    
    	  if (count == -1)
    	    throw new IOException("end-of-stream");
    	  offset += count;
    	}
    	return data;
        }

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Salinas
    Come faccio ad applicare la tua ultima soluzione in questo caso?
    Qui non utilizza buffer.
    Perché non dovresti? L'ho detto: il BufferedInputStream basta metterlo in un DataInputStream!

    Detto con un breve stralcio di codice:

    codice:
    InputStream is = cliente.getInputStream();
    BufferedInputStream bis = new BufferedInputStream(is);
    
    DataInputStream dis = new DataInputStream(bis);
    
    int size = dis.read();
    
    byte[] packet = new byte[size];
    
    dis.readFully(packet);
    E nota la lettura di 1 singolo byte con read() che ritorna un int con valore 0-255 ... molto più comodo!!

    Ed è tutto lì ...
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    396
    ok.
    Scusa, ma questa operazione la posso far eseguire mentre manda altri pacchetti?
    Mi spiego meglio, ho questa funzione che manda di continuo:
    codice:
    bw.write(VERSION);
        while(!inattivo){
        if(available==false){  // gestione concorrente con la scrittura dei pacchetti
        //bw.write(hexString(packet)+"\n");
        if (packet.length > 255)
    	    throw new IOException("pacchetto troppo lungo\n");
        if (packet.length == 0)
    	    throw new IOException("pacchetto troppo corto\n");
        bw.write((byte)packet.length);
        bw.write(packet);
        bw.flush();
    
        //System.out.print(pak);
        available=true;  
          }
        }
    Adesso posso aggiungere la possibilità di leggere pacchetti dentro lo stesso while?
    oppure si blocca nel caso i pacchetti non fossero inviati?

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Salinas
    Scusa, ma questa operazione la posso far eseguire mentre manda altri pacchetti?

    Adesso posso aggiungere la possibilità di leggere pacchetti dentro lo stesso while?
    oppure si blocca nel caso i pacchetti non fossero inviati?
    La questione è un'altra .... dipende dal protocollo.
    Nel senso: è un protocollo "domanda/risposta"??? Il flusso di comunicazione, in un certo istante, è sempre solo in un verso o nell'altro??

    Se è così, allora ok, è semplice. Prima A invia a B, poi B come risposta invia ad A, ecc....
    Quindi tu invii un pacchetto, poi leggi un pacchetto, ecc...

    Se invece è un protocollo fortemente asincrono, cioè mentre tu stai inviando un pacchetto, l'altro host te ne invia un'altro per i motivi suoi, allora devi gestirlo diversamente, con 2 thread uno di trasmissione e l'altro di ricezione, con tutte le problematiche inerenti all'uso di più thread ed eventuale comunicazione tra di loro.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    396
    Sono nella seconda situazione.
    Il client manda quando vuole i pacchetti.

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Salinas
    Sono nella seconda situazione.
    Il client manda quando vuole i pacchetti.
    No alt, precisiamo. In un tipico protocollo domanda/risposta (come HTTP per dirne uno noto), il client invia la richiesta quando gli pare e il server invia una risposta solo a seguito di una domanda dal client.

    Quindi? Quello che devi chiarire meglio è la correlazione che c'è tra ciò che un host invia e ciò che riceve.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    396
    Ho problemi di sincronizzazione, come faccio a sapere quando il client ha scritto qualcosa? c'è un comando?
    In questo modo posso stoppare gli altri thread e leggere quello che mi sta mandando il cliente.
    Inoltre evito di stare sempre a controllare quello che arriva, anche se non arriva niente.

  10. #10
    Utente di HTML.it
    Registrato dal
    Jun 2008
    Messaggi
    396
    No alt, precisiamo. In un tipico protocollo domanda/risposta (come HTTP per dirne uno noto), il client invia la richiesta quando gli pare e il server invia una risposta solo a seguito di una domanda dal client.

    Quindi? Quello che devi chiarire meglio è la correlazione che c'è tra ciò che un host invia e ciò che riceve.
    Il server invia sempre pacchetti al client.
    Il client può inviare pacchetti al server, quando vuole.

    Adesso dato che il server è sempre impegnato ad inviare pacchetti, si inceppa se gli dico di vedere se i pacchetti sono anche arrivati dal client.
    Quindi vorrei poter sapere quando il client ha scritto qualcosa, in modo da dover stoppare il server solo quando c'è qualcosa da leggere, altrimenti può continuare ad inviare i pacchetti.

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.