2010-10-24 11 views
9

Ho letto alcuni snippet di codice socket Java e ho scoperto che nella comunicazione socket, per inviare messaggi in sequenza, non è necessario separarli a mano, il lo scrittore/lettore streaming fa automaticamente le cose per te. Ecco un esempio:java socket writeUTF() e readUTF()

writer.java 
writeUTF("Hello"); 
writeUTF("World"); 


reader.java 
String a=readUTF(); // a=Hello 
String a=readUTF(); // b=World 

Ho provato questo snippet di codice e funziona correttamente. Tuttavia, mi chiedo se questo tipo di stile di codifica dovrebbe funzionare correttamente. C'è qualche rischio potenziale di usare il socket stream in sequenza senza separare esplicitamente ogni segmento?

+0

Che cosa si intende per 'separare esplicitamente ciascun segmento' Mina? Non c'è modo in TCP nemmeno di farlo, assumendo che si stia parlando di segmenti TCP reali come da RFC. Per favore chiarisci la tua domanda. – EJP

+0

Bene, di solito aggiungo alcuni caratteri speciali come "###" e li rilevo dal lato del lettore. È piuttosto sciocco ma non ho altri modi. –

risposta

1

Secondo la documentazione i metodi readUTF e writeUTF funzionano con una versione modificata di UTF8 che aggiunge anche la lunghezza del carattere da leggere all'inizio.

Ciò significa che l'operazione di lettura attenderà fino a quando non è stato recuperato un numero sufficiente di caratteri prima di restituire la stringa. Ciò significa che sono effettivamente segmentati anche se non lo si vede poiché si limitano a decorare i flussi della presa con DataInputStream e DataOutputStream.

In conclusione, sì, dovrebbe essere abbastanza sicuro, poiché l'API stessa si occuperà di separare i singoli messaggi.

24

Il writeUTF() e readUTF() scrivono la lunghezza della stringa (in byte, quando codificata come UTF-8) seguita dai dati e utilizza una codifica modified UTF-8. Quindi ci sono alcuni potenziali problemi:

  • La lunghezza massima delle stringhe che può essere gestito in questo modo è 65535 per puro ASCII, meno se si utilizzano caratteri non ASCII - e non si può facilmente prevedere il limite in questo caso, diverso dal presupposto conservativo di 3 byte per carattere. Quindi, se sei sicuro di non inviare mai le stringhe più di 20k, starai bene.
  • Se l'applicazione ha bisogno di comunicare con qualcos'altro (che non è scritto in Java), l'altra parte potrebbe avere difficoltà a gestire l'UTF-8 modificato. Per la comunicazione interna all'applicazione, non devi preoccuparti.
+0

Risposta molto impressionante, grazie mille. –

0

java.net.Socket funziona bene, il flusso attende readUTF();

Ma quando si utilizza il CumulativeProtocolDecoder, non sarà, getta java.io.EOFException

+1

Dubito seriamente che questa affermazione sia corretta. 'EOFException' viene lanciato quando il peer ha chiuso la connessione. Ci si aspetta che una lettura dei dati che è ancora incompleta lanci un 'SocketTimeoutException'. – EJP