|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
[Java] socket e codifica stringhe
Mi sono scritto un applicazione lato server (per il momento) che gestisce la ricezione di un file. Per mia comodità ho usato DataInputStream per leggere dalla socket, e DataOutputStream per scrivere su file.
Ora volevo provare il programma, quindi mi sono detto: "usa telnet e vedi", ma devo avere qualche problema con la codifica delle stringhe. Una volta che un client si connette, apro gli streams e faccio: Codice:
String filename = input.readUTF();
// sì, voglio ricevere il file
output.writeInt(ACK);
// prendo dimensione del file
int size = input.readInt();
// trasferisco il file
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Due cose:
1] prova a inserire la chiamata a .readUTF() dentro un blocco try-catch in cui catturi l'eccezione di tipo: UTFDataFormatException. Esegui e vedi se in output si verifica questa eccezione [the bytes do not represent a valid UTF-8 encoding of a string... come dicono i javadoc dell'interfaccia DataInput] 2] leggiti il contratto dichiarato dall'interfaccia DataInput per quanto riguarda l'implementazione del metodo .readUTF(): Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
Si comporta come se non ricevesse una specie di fine stringa, (nel vecchio e deprecato readLine() sarebbe il CRLF), oppure come se non svuotasse il buffer.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Prova a forzare il flush() dell'input stream, non so se possa servire almeno per avere un parziale output.
Posto i sorgenti del metodo .readUTF() della classe DataInputStream, magari con un'occhiata qualcuno di più esperto può capire quale sia il problema. Codice:
545 /**
546 * See the general contract of the <code>readUTF</code>
547 * method of <code>DataInput</code>.
548 * <p>
549 * Bytes
550 * for this operation are read from the contained
551 * input stream.
552 *
553 * @return a Unicode string.
554 * @exception EOFException if this input stream reaches the end before
555 * reading all the bytes.
556 * @exception IOException the stream has been closed and the contained
557 * input stream does not support reading after close, or
558 * another I/O error occurs.
559 * @exception UTFDataFormatException if the bytes do not represent a valid
560 * modified UTF-8 encoding of a string.
561 * @see java.io.DataInputStream#readUTF(java.io.DataInput)
562 */
563 public final String readUTF() throws IOException {
564 return readUTF(this);
565 }
566
567 /**
568 * Reads from the
569 * stream <code>in</code> a representation
570 * of a Unicode character string encoded in
571 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
572 * this string of characters is then returned as a <code>String</code>.
573 * The details of the modified UTF-8 representation
574 * are exactly the same as for the <code>readUTF</code>
575 * method of <code>DataInput</code>.
576 *
577 * @param in a data input stream.
578 * @return a Unicode string.
579 * @exception EOFException if the input stream reaches the end
580 * before all the bytes.
581 * @exception IOException the stream has been closed and the contained
582 * input stream does not support reading after close, or
583 * another I/O error occurs.
584 * @exception UTFDataFormatException if the bytes do not represent a
585 * valid modified UTF-8 encoding of a Unicode string.
586 * @see java.io.DataInputStream#readUnsignedShort()
587 */
588 public final static String readUTF(DataInput in) throws IOException {
589 int utflen = in.readUnsignedShort();
590 byte[] bytearr = null;
591 char[] chararr = null;
592 if (in instanceof DataInputStream) {
593 DataInputStream dis = (DataInputStream)in;
594 if (dis.bytearr.length < utflen){
595 dis.bytearr = new byte[utflen*2];
596 dis.chararr = new char[utflen*2];
597 }
598 chararr = dis.chararr;
599 bytearr = dis.bytearr;
600 } else {
601 bytearr = new byte[utflen];
602 chararr = new char[utflen];
603 }
604
605 int c, char2, char3;
606 int count = 0;
607 int chararr_count=0;
608
609 in.readFully(bytearr, 0, utflen);
610
611 while (count < utflen) {
612 c = (int) bytearr[count] & 0xff;
613 if (c > 127) break;
614 count++;
615 chararr[chararr_count++]=(char)c;
616 }
617
618 while (count < utflen) {
619 c = (int) bytearr[count] & 0xff;
620 switch (c >> 4) {
621 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
622 /* 0xxxxxxx*/
623 count++;
624 chararr[chararr_count++]=(char)c;
625 break;
626 case 12: case 13:
627 /* 110x xxxx 10xx xxxx*/
628 count += 2;
629 if (count > utflen)
630 throw new UTFDataFormatException(
631 "malformed input: partial character at end");
632 char2 = (int) bytearr[count-1];
633 if ((char2 & 0xC0) != 0x80)
634 throw new UTFDataFormatException(
635 "malformed input around byte " + count);
636 chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
637 (char2 & 0x3F));
638 break;
639 case 14:
640 /* 1110 xxxx 10xx xxxx 10xx xxxx */
641 count += 3;
642 if (count > utflen)
643 throw new UTFDataFormatException(
644 "malformed input: partial character at end");
645 char2 = (int) bytearr[count-2];
646 char3 = (int) bytearr[count-1];
647 if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
648 throw new UTFDataFormatException(
649 "malformed input around byte " + (count-1));
650 chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
651 ((char2 & 0x3F) << 6) |
652 ((char3 & 0x3F) << 0));
653 break;
654 default:
655 /* 10xx xxxx, 1111 xxxx */
656 throw new UTFDataFormatException(
657 "malformed input around byte " + count);
658 }
659 }
660 // The number of chars produced may be less than utflen
661 return new String(chararr, 0, chararr_count);
662 }
663 }
Tanto per verificare che non sia un problema di formato incompatibile causato da Telnet. PS.: nella parte in grassetto del codice: bytearr è un membro della classe dichiarato così: Codice:
/** 56 * working arrays initialized on demand by readUTF 57 */ 58 private byte bytearr[] = new byte[80]; 59 private char chararr[] = new char[80];
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 19-09-2008 alle 15:52. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
ho provato anche con netcat, stessa storia.....ora però mi sono scritto il client e funziona, almeno sembra!
ancor di più penso sia un problema dovuto al fatto che il server non si accorge di quello che dice il client: per il server il nome del file potrebbe essere lungo righe e righe di testo scritto con questi tool. beh in ogni caso grazie per l'aiuto! PS: se vuoi posto le 2 classi complete
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:09.




















