View Full Version : [J2ME] error 10053 during TCP read
Questa eccezione mi spunta casualmente nella mia MIDlet...
Suppongo che sia un problema relativo a qualche API che termina senza aver letto i dati perchè non sono arrivati...
Vi allego il codice di lettura e scrittura sul socket:
socket = (SocketConnection)Connector.open("socket://"
+ midlet.getServer());
socket.setSocketOption(SocketConnection.LINGER, 5);
DataOutputStream dataOutput = socket.openDataOutputStream();
dataOutput.writeInt(midlet.getProfile().getUserId());
dataOutput.writeByte(action);
byte[] packetData = packet.toByteArray();
dataOutput.writeInt(packetData.length);
dataOutput.write(packetData);
dataOutput.close();
DataInputStream dataInput = socket.openDataInputStream();
int payloadSize = dataInput.readInt();
if(payloadSize < 0 || payloadSize > 102400)
{
throw new IOException("Bad packet");
}
byte[] payload = new byte[payloadSize];
int readSize = dataInput.read(payload);
if(readSize != payloadSize)
{
throw new IOException("Bad packet length");
}
dataInput.close();
return new IncomingPacket(payload);
Il probema è che non so nemmeno a che riga viene generata l'eccezione...
A occhio tutte quelle API di lettura e scrittura mi sembrano bloccanti, quindi non capisco dove sia il problema...
Ehm...ho una certa urgenza...
Grazie a tutti
Up :cry:
Non ho la risposta.
Hai provato rimuovendo il LINGER? Anche se 5 secondi dovrebbero essere ottimi e abbondanti.
Prova anche a leggere payloadSize byte da DataInputStream anzichè riempire un buffer (nonostante l'uso del buffer sia una soluzione migliore). Più che altro per vedere quando si verifica l'eccezione.
Azz...
Dal debugger non si verifica mai :muro: Mentre nell'esecuzione normale molto spesso...
Prima avevo EclipseME e stranamente il debugger ha smesso di funzionare (non partiva più l'applicazione in debugging, mentre in Run andava tranquillamente), il bello è che me l'ha fatto sia sul desktop che sul protatile in momenti diversi e con le stesse modalità...ho reinstallato tutto 20 volte, ma continua a non funzionare :muro:
Ora ho messo Carbide.j e il debugger funziona, ma sull'emulatore Nokia il problema non si presenta. Invece si presenta sull'emulatore Sun sul quale non posso debuggare :muro: :muro: :muro:
^TiGeRShArK^
16-06-2006, 09:48
Questa eccezione mi spunta casualmente nella mia MIDlet...
Suppongo che sia un problema relativo a qualche API che termina senza aver letto i dati perchè non sono arrivati...
Vi allego il codice di lettura e scrittura sul socket:
socket = (SocketConnection)Connector.open("socket://"
+ midlet.getServer());
socket.setSocketOption(SocketConnection.LINGER, 5);
DataOutputStream dataOutput = socket.openDataOutputStream();
dataOutput.writeInt(midlet.getProfile().getUserId());
dataOutput.writeByte(action);
byte[] packetData = packet.toByteArray();
dataOutput.writeInt(packetData.length);
dataOutput.write(packetData);
dataOutput.close();
DataInputStream dataInput = socket.openDataInputStream();
int payloadSize = dataInput.readInt();
if(payloadSize < 0 || payloadSize > 102400)
{
throw new IOException("Bad packet");
}
byte[] payload = new byte[payloadSize];
int readSize = dataInput.read(payload);
if(readSize != payloadSize)
{
throw new IOException("Bad packet length");
}
dataInput.close();
return new IncomingPacket(payload);
Il probema è che non so nemmeno a che riga viene generata l'eccezione...
A occhio tutte quelle API di lettura e scrittura mi sembrano bloccanti, quindi non capisco dove sia il problema...
Ehm...ho una certa urgenza...
Grazie a tutti
Hola....
causa zanzare, caldo e secchiate d'acqua che qualke idiota buttava dal balcone alle 4 e mezzo sono lievemente fuso stamattina :p
La prima cosa che ti conviene fare è secondo me di fare una stampa sul form del cellulare ad ogni riga in modo che localizzi il punto esatto dove avviene l'errore...
Un'idea ke mi è venuta in mente è che non hai fatto DataOutput.flush() prima di fare il close.....
Prova se funge in quel modo, altrimenti come ti ho detto di tocca fare quelle stampe sul form della MIDlet :p
Fammi sapere, ke al max provo a pensare a qualcos'altro qdo mi sveglio :stordita:
^TiGeRShArK^
16-06-2006, 09:51
Dimenticavo....
Prova anche ad usare in lettura il metodo .available() sull'input stream che ti restituisce il numero di byte che è possibile leggere senza che si blocchi. :p
Classico caso in cui scopri, anzi non scopri ma resti col dubbio, che il problema sia nell'emulatore.
Hai provato con Netbeans e il suo mobility pack?
^TiGeRShArK^
16-06-2006, 10:10
Classico caso in cui scopri, anzi non scopri ma resti col dubbio, che il problema sia nell'emulatore.
Hai provato con Netbeans e il suo mobility pack?
:mbe:
ah... con esecuzione non intendeva l'esecuzione sul cellulare reale? :fagiano:
Stavo provando a fare una esecuzione multipla con 4 emulatori ed il cellulare...per ora il problema si è sempre verificato sull'emulatore Sun del WTK...
Prova anche ad usare in lettura il metodo .available() sull'input stream che ti restituisce il numero di byte che è possibile leggere senza che si blocchi. :p
Ma a me mi va bene se è bloccante...o no ?
theClimber
16-06-2006, 10:33
Guardando le doc di socket connection mi viene un sospetto:
http://www.j2medev.com/api/midp/javax/microedition/io/SocketConnection.html
Ad un certo punto dicono:
Closing Streams
Every StreamConnection provides a Connection object as well as an InputStream and OutputStream to handle the I/O associated with the connection. Each of these interfaces has its own close() method. For systems that support duplex communication over the socket connection, closing of the input or output stream SHOULD shutdown just that side of the connection. e.g. closing the InputStream will permit the OutputStream to continue sending data.
Once the input or output stream has been closed, it can only be reopened with a call to Connector.open(). The application will receive an IOException if an attempt is made to reopen the stream.
Prova a chiudere le connection alla fine, non vorrei che ci sianoi comportamenti diversi. Mi sarei aspettato un MUST al posto di SHOULD (che, se ci si riferisce ai livelli IETF, e' un reccomended... http://rfc.net/rfc2119.html). :confused:
Ciao
La lettura con:
inputStream.read(buffer);
è bloccante ma non è detto che legga il numero di byte corrispondente alla lunghezza del buffer.
Probabilmente per fare quello che intendi sarebbe più idonea una soluzione del tipo (occhio che vado "a braccio"):
int numeroDiByteDaLeggere = XYZ;
byte[] buffer = new byte[XYZ];
int offset = 0;
do {
int len = buffer.length - offset;
int count = inputStream.read(buffer, offset, len);
offset += count;
} while(offset < numeroDiByteDaLeggere);
Cioè, dato il contratto di read(byte[]), secondo cui il metodo restituisce il controllo anche nel caso in cui siano stati letti un numero di byte insufficienti a riempire l'array, se intendi usarlo per leggere (come è assolutamente normale) un numero dato di byte allora devi necessariamente prevedere un meccanismo che controlli che il numero di byte letti corrisponda al numero di byte richiesti. Poi può darsi (ed è il caso più frequente) che si faccia un solo passaggio in quel ciclo. Ma gli InputStream non lo dicono.
Comunque questo non è la causa dell'eccezione: qui c'è qualcuno che taglia la connessione a bruciapelo e non è sicuramente il codice che hai scritto a farlo.
^TiGeRShArK^
16-06-2006, 10:40
Stavo provando a fare una esecuzione multipla con 4 emulatori ed il cellulare...per ora il problema si è sempre verificato sull'emulatore Sun del WTK...
mmmmmm....
potrebbe anke essere un prob dell'emulatore allora....anke perchè im pare che hai detto che quello nokia ti funziona.
Prova a googlare un pò per vedere se anche altri hanno avuto lo stesso problema sull'emulatore SUN, perchè soprattutto quando si usano la rete o i device del cellulare, sull'emulatore sorgono sempre innumerevoli problemi....
^TiGeRShArK^
16-06-2006, 10:49
Comunque questo non è la causa dell'eccezione: qui c'è qualcuno che taglia la connessione a bruciapelo e non è sicuramente il codice che hai scritto a farlo.
Io con gli stream in rete non ho mai avuto a ke fare direttamente perchè mi sono sempre appoggiato a dei framework esterni, cmq quando scrivevo con degli stream su file gli unici problemi casuali che avevo era quando non facevo il flush sulla connessione in out prima di chiuderla...
non è che per caso qualche emulatore o il cellulare non invia correttamente tutti i dati e quindi si impalla un pò tutto? :fagiano:
hai provato se aggiungendo il flush migliora qualcosa o si ha sempre la stessa situazione? :fagiano:
int numeroDiByteDaLeggere = XYZ;
byte[] buffer = new byte[XYZ];
int offset = 0;
do {
int len = buffer.length - offset;
int count = inputStream.read(buffer, offset, len);
offset += count;
} while(offset < numeroDiByteDaLeggere);
Ok...passo a questa modo di leggere... E' sicuramente più sicuro...
Sul server ho anche messe una pausa di 1s prima di chiudere il socket e gli stream... Proprio per evitare che gli chiudesse la connessione "in faccia"...
Tra l'altro sia sul server che sul client ho fatto in modo di generare un'eccezione nel caso in cui il numero di byte ricevuti sia inferiore al numero di byte richiesti dal pacchetto...
Così sul server mi si blocca, ma c'è il timeout che mi viene in aiuto... Ma sul client ? Se non arrivano tutti i byte che succede ? Dopo quanto viene generata un'eccezione ?
Questa potrebbe fare al caso mio:
readFully
public void readFully(byte[] b)
throws IOException
Reads some bytes from an input stream and stores them into the buffer array b. The number of bytes read is equal to the length of b.
This method blocks until one of the following conditions occurs:
* b.length bytes of input data are available, in which case a normal return is made.
* End of file is detected, in which case an EOFException is thrown.
* An I/O error occurs, in which case an IOException other than EOFException is thrown.
If b is null, a NullPointerException is thrown. If b.length is zero, then no bytes are read. Otherwise, the first byte read is stored into element b[0], the next one into b[1], and so on. If an exception is thrown from this method, then it may be that some but not all bytes of b have been updated with data from the input stream.
Edit: ora mi viene un dbbio, forse questa non è bloccante... Nel senso che se non ci sono dati disponibili ritorna un'eccezione, non è che sta lì ad aspettare l'arrivo di tutti i dati...
Nel codice che ho incollato il ciclo di lettura si blocca quando il socket va in timeout (5 secondi senza trasmissione) perchè il tentativo di lettura incontrerà una IOException (cosa che è certa secondo la definizione di un Socket nelle librerie di Java).
readFully è più che ok. Io mi ero distrattamente fermato a livello di InputStream.
Usa quella, hai un DataInput, ti accorcia il codice di un bel po'. Nel caso in cui non sia disponibili buffer.length byte il metodo "aspetta" che arrivino. Si fermerà prima di length solo se il server spari una sequenza di byte riconosciuta come un End Of File (che riconoscerai intercettando per prima un'eccezione EOFException) o non invii i byte richiesti prima del timeout del socket (in quel caso avremo una delle eccezioni del caso 3).
La sequenza EOF mi crea sicuramente qualche problema... Essendo dati "grezzi" sicuramente mi si potrebbe presentare in qualche salsa...
Lavorerò un po' sul ciclo che mi hai proposto...ad una prima implementazione purtroppo mi si bloccano alcune richieste (non so il perchè)...
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.