Newsgroup: it.comp.java
Titolo: Lettura socket

Ciao,
devo leggere un messaggio da un socket, tale messaggio pero' e' spedito 
in due parti attraverso due write sullo stesso socket, io devo leggere 
tutto il messaggio, che metodi e strutture mi consigliate di usare per 
questa operazione?
L'implementazione da me usata e' la seguente che pero' da dei problemi:
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
          int len;
          while( true ) {
             len = inStream.read(buf);
	    if ( len <= 0 )
	    	break;
	    else {
                os.write(buf, 0, len);
	       System.out.println( new String(buf) );
	    }
	 }
Grazie.

Ti consiglio di utilizzare una classe, dove memorizzi un ID che identifichi
quel messaggio, e un indice del blocco.
Tra i due write, potrbbe capitarne un'altro di qualche altro thread che
trova la risorsa socket libera (o che la sincronizzazione aveva messo in
coda) e li scattano le noie.

 	 }
Direi che la tua implementazione sia corretta.
Forse sostituirei println con print, ma nient'altro.
Quali sono i problemi che lamenti?
-- Dario

 ha scritto nel messaggio
news:1106_1028042293@dylan...


 il codice purtroppo ora non ce l'ho sottomano.
Purtroppo a questo punto senza il frammento di codice incriminato
e senza una esatta stampa delle exceptions fatta dalla JVM
non ti posso essere di molto aiuto.
-- Dario


Allora,
l'exception ritornata e' la seguente:
"java.net.SocketException: Connection reset by peer: Connection reset by 
peer
ERROR: error Connection reset by peer: Connection reset by peer"
Ora quello che succede e' questo:
il server invia il messaggio con due write (purtroppo io non posso 
cambiare l'implementazione del server scritto in c++), con la prima 
invia l'header http, con la seconda il resto del msg che e' un envelope 
soap, se io leggo solo le prime 4 righe ( con un ciclio for) costituite 
dall'header http e dalla successiva riga vuota, il tutto va bene, cioe' 
non mi appare il msg di connection reset by peer, il problema c'e' 
quando cerco di leggere piu' righe rispetto alle 5 dell'header http, il 
che mi fa pensare che sia quasi un problema di sincronizzazione visto 
che il server invia il msg con due write e quindi arriva in due parti,
Con il seguente codice:
String response = "";
	for ( int i = 0; i < 4; i++ ) {
            response = inStream.readLine( );
            System.out.println( response );
	}
mi stampa le righe dell'header http e non mi da errore, ma se cerco di 
leggere tutto il messaggio con il seguente codice:
while ( ( response = inStream.readLine( ) ) != null )
	   System.out.println( response );
mi stampa l'header http ma poi quando dovrebbe iniziare la stampa 
dell'envelope (seconda parte del msg inviata dalla seconda write del 
server) mi appare l'eccezione.
Dovrei forse sincronizzare qualche cosa?

 	   System.out.println( response );
con qualcosa del tipo:
  int b;
  while(inStream.available() > 0 && (b = inStream.read()) != -1)
    System.out.write(b);
e vedi cosa effettivamente viene letto e dove si ha l'eccezione
(alla fine del messaggio o in mezzo?).
Poi con questi dati se ne riparla.
-- Dario


Ciao,
  questo e' il codice che ho provato:
inStream = new BufferedInputStream ( s.getInputStream( ) );
System.out.println("\nAvailable = " + inStream.available());
 
	while(inStream.available() > 0 && (b = inStream.read()) != -1)
            System.out.write(b);
 
Come consigliato da te, il problema ora e' che available() mi ritorna il 
valore 0 percui non entra mai nel ciclo while, questo e' strano perche' 
almeno la prima parte del msg con il codice da me precedentemente 
postato me la stampava.


Togliendo dal ciclo while il controllo available, si comporta come al 
solito, con lo stesso problema, mi legge l'header http con la successiva 
riga vuota,inviato dalla prima write, e poi mi da l'eccezione, nel 
momento in cui dovrebbe leggere la seconda parte del msg (l'envelope 
soap) inviata dalla seconda write del server.

 postato me la stampava.
Penultimo tentativo...:
Prova (solo x debugging):
  int countA = 0;
  inStream = s.getInputStream(); // NON: new BufferedInputStream...
  while(true) {
     int a;
     try {
       a = inStream.read();
     } catch (Exception e) {
       a = 0;
       countA++;
       System.out.println();
       System.out.println("*** Exception: "+e+" countA: "+countA);
       e.printStackTrace(System.out);
       System.out.println("***");
       if (countA > 100)
          break;
     }
     if (a == 0) {
       Thread.sleep(1000/10);
       continue;
     }
     for (int i=0; i<a; i++)
        try {
           int b = inStream.read();
           System.out.write(b);
        } catch (Exception e) {
          countB++;
          System.out.println();
          System.out.println("*** Exception: "+e+" i: "+i+" a: "+a);
          e.printStackTrace(System.out);
          System.out.println("***");
        }
  }
e posta *tutto* cio' che viene stampato.
Speriamo sia la volta buona.
-- Dario


Mi vengono stampati i seguenti msg:
*** Exception: java.net.SocketException: Connection reset by peer: 
Connection reset by peer i: 0 a: 72
java.net.SocketException: Connection reset by peer: Connection reset by peer
         at java.net.SocketInputStream.socketRead0(Native Method)
         at java.net.SocketInputStream.read(SocketInputStream.java:116)
         at java.net.SocketInputStream.read(SocketInputStream.java:144)
         at xdaqAdapter.XDaqElement.sendXDaqMessage(XDaqElement.java:342)
         at xdaqAdapter.XDaqElement.execute(XDaqElement.java:131)
         at xdaqAdapter.XDaqHost.configure(XDaqHost.java:165)
         at 
xdaqAdapter.XDaqPartition.configureXDaqHost(XDaqPartition.java:280)
         at xdaqAdapter.testAdapter.executeCommand(testAdapter.java:416)
         at xdaqAdapter.testAdapter.console(testAdapter.java:239)
         at xdaqAdapter.testAdapter.main(testAdapter.java:157)
***
TTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnn
Come vedi mi stampa solo l'header http e tutto il resto (inviato dalla 
seconda write del server) manca..

 seconda write del server) manca..
Non sono d'accordo.
1. Se la stampa che dai e' giusta, allora e' stata generata una eccezione
   "Connection reset by peer" *prima* (!_prima_!) della ricezione degli header
   che infatti sono stampati *dopo* la stampa della exception.
2. E' *molto* strano l'header
   Content-Length: nnn
   nnn dovrebbe essere un numero e non 3 lettere!
3. Per caso il server (che dici che fa due write distinte)
   non e' che fra una write e l'altra chiude la connessione per caso?
4. Non mi spiego la mancanza di qualsiasi stampa dopo la riga
   Content-Length: nnn
   Se hai usato il mio frammento di codice cio' sembra indicare
   che il programma e' ancora in loop (l'unico break non e' stato mai
   raggiunto.
Prova ad eseguire questo *ultimo* tentativo:
  int count = 0;
  int countA = 0;
  inStream = s.getInputStream(); // NON: new BufferedInputStream...
  loop:
  while(true) {
     int a;
     try {
       a = inStream.read();
       System.out.println();
       System.out.println("*** a: "+a);
       System.out.println("***");
     } catch (Exception e) {
       a = 0;
       countA++;
       System.out.println();
       System.out.println("*** Exception: "+e+" countA: "+countA);
       e.printStackTrace(System.out);
       System.out.println("***");
       if (countA > 100)
          break;
     }
     if (a == 0) {
       Thread.sleep(1000/10);
       if (count++ <= 100)
          continue;
       System.out.println("");
       System.out.println("*** break forced");
     }
     for (int i=0; i<a; i++)
        try {
           int b = inStream.read();
           if (b == -1) {
              System.out.println();
              System.out.println("*** inStream.read returned -1");
              break loop;
           }
           if (b == 0) {
              System.out.println();
              System.out.println("*** read a zero byte!");
              System.out.println("***");
           } else
             System.out.write(b);
        } catch (Exception e) {
          countB++;
          System.out.println();
          System.out.println("*** Exception: "+e+" i: "+i+" a: "+a);
          e.printStackTrace(System.out);
          System.out.println("***");
        }
  }
  System.out.println();
  System.out.println("*** end");
Fai un ultimo post della stampa cosi' come viene e...
.. vediamo cosa succede!
-- Dario
P.S. Questa e' una sessione di test pubblica su newsgroup...
     ... divertente o viola qualche netiquette ?


CIao, con questo test mi viene stampato il seguente testo come riportato:
*** a: 72
***
*** Exception: java.net.SocketException: Connection reset by peer: 
Connection reset by peer i: 0 a: 72
java.net.SocketException: Connection reset by peer: Connection reset by peer
         at java.net.SocketInputStream.socketRead0(Native Method)
         at java.net.SocketInputStream.read(SocketInputStream.java:116)
         at java.net.SocketInputStream.read(SocketInputStream.java:144)
         at xdaqAdapter.XDaqElement.sendXDaqMessage(XDaqElement.java:351)
         at xdaqAdapter.XDaqElement.execute(XDaqElement.java:131)
         at xdaqAdapter.XDaqHost.configure(XDaqHost.java:165)
         at 
xdaqAdapter.XDaqPartition.configureXDaqHost(XDaqPartition.java:280)
         at xdaqAdapter.testAdapter.executeCommand(testAdapter.java:416)
         at xdaqAdapter.testAdapter.console(testAdapter.java:239)
         at xdaqAdapter.testAdapter.main(testAdapter.java:157)
***
TTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length:
*** a: 110
***
nnn
*** inStream.read returned -1
*** end
C'e' un piccolo errore di lettura che mi mangia il primo carattere 
dell'header 'H' e l'ultimo 'n' in quanto la length dovrebbe essere nnnn, 
in realta' ci dovrebbe essere un numero, ma ho trovato spesso anche 
questa sigla nnnn, probabilmente quando si usano messaggi soap.
L'header http e' ok, ma non mi ritorna il resto, il server fa due write 
consecutive, con una invia l'header, con l'altra il resto, e in mezzo 
alle due istruzioni non c'e' niente, quindi il socket non viene chiuso.
   Ciao