My question is: is there a way to perform a socket OutputStream shutdown or it is not right/fully implemented as it should be by nokia? (J2ME nokia implementation, tested at nokia c6-00 and not closing stream, tested on emulator and works fine)
The main problem is that J2SE server application does not get the end of stream info, the condition read(buffer) == -1 is never true, tries to read from an empty stream and hangs until client is force-killed. This works with a very, very, very ugly workaround on the server side application
Thread.sleep(10);//wait some time for data else you would get stuck........
while ((count = dataInputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, count);
if (count != BUFFER_SIZE_1024 || dataInputStream.available() == 0) { //the worlds worst condition ever written... but works
break;
}
Thread.sleep(10);//wait for data input to get some data for dataInputStream.available() to return != 0 if client still sends data else you would not read all data......
}
but this solution is absolutely not acceptable (i dont know something about nokia java coding, i’m missing something, or is it maybe similar to a some sort of nokia-J2ME coding standard and i should get used to it or change platform)
I can’t close the client socket after sending data because server sends a response to the client after receiving and processing data.
It looks like this: J2ME client -> J2SE server (hangs on read because client does not perform a outputstream shutdown) -> J2ME
I’ve tried to:
close the dataOutputStream on the J2ME client – no effect
setSocketOptions (KEEPALIVE, SNDBUF and others) – no effect or errors
nothing seems to work on the target device
sorry but i’m a bit furious right now after this nonsense fight with little java.
I’have searched for the solution but non seems to work
Client code:
SocketConnection socketConnection = (SocketConnection) Connector.open("socket://" + ip + ":" + port);
int count;
byte[] buffer = new byte[BUFFER_SIZE_1024];
// client -> server
DataOutputStream dataOutputStream = new DataOutputStream(socketConnection.openDataOutputStream());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
while ((count = byteArrayInputStream.read(buffer)) != -1) {
dataOutputStream.write(buffer, 0, count);
dataOutputStream.flush();
}
dataOutputStream.close();
byteArrayInputStream.close();
I’ve tried the code with the same effect – on the emulator works like a charm, on the device hangs but i solved my problem as follows:
On the J2ME client before sending the 1024 byte packet I’m sending its length and its state (
IsNextorIsLast) after this on the J2SE server side in awhile(true)loop. I’m reading first the length with areadShort, then state with areadByte(I know it’s better to combine it on a one short but I didn’t knew if it will work and if the effort was worth it and now when it works I’m not touching this, besides it is easy to add a new state if necessarily and it works quite fast).After this server goes in to a second nested loop [
while (dataInputStream.available() < length) {}– I’ll have to put here a timeout but I’ll worry about that later. Also note that on J2MEdataInputStream.available()always returns a 0 (!) so in the J2ME client read in this place is afor (int i = 0; i < length... loopreading a single byte]When the
while(dataInputStream.available() ...loop breaks I’m reading a block of data which length I have, and if the state isIsLastI break thewhile(true)loop. Works perfectly and stable.Thanks for the advice and hope this info will help someone