views:

273

answers:

2

Hi guys, I am trying to develop a TCP client that runs on mobile devices using MIDP 2.0 and CLDC 1.1. I am trying some sample code, and I have the following problem:

I get a weird exception when I try to read the data back (From the MIDlet).

This is my code:

            //Wait for an incoming message
            firstByte = in.read();
            ByteArrayOutputStream textRecieved = new ByteArrayOutputStream();   //Will be used to hold the data
            if (firstByte >= 0 )
            {                    
                int messageSize = this.in.available();

                //Read the message
                while (messageSize > 0)
                {
                    byte[] buffer = new byte[messageSize];  
                    this.in.read(buffer);
                    textRecieved.write(buffer);
                    messageSize = this.in.available();   //Just in case the server sent the request in chunks.
                    System.out.println("Reading...");
                }
            }
            textRecieved.close();

This is the exception I get:

java.io.IOException: Unknown error 10053 during socket::read 
        at com.sun.midp.io.j2me.socket.Protocol.read0(), bci=0
        at com.sun.midp.io.j2me.socket.Protocol.nonBufferedRead(), bci=12
        at com.sun.midp.io.BufferedConnectionAdapter.readBytes(), bci=36
        at com.sun.midp.io.BaseInputStream.read(), bci=227
        at com.sun.midp.io.BufferedInputStream.fill(), bci=172
        at com.sun.midp.io.BufferedInputStream.read(), bci=16
        at hello.Client.run22222(Client.java:60)
        at hello.HelloMIDlet.startApp(HelloMIDlet.java:193)
        at javax.microedition.midlet.MIDletTunnelImpl.callStartApp(), bci=1
        at com.sun.midp.midlet.MIDletPeer.startApp(), bci=7
        at com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=269
        at com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=52
        at com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=8
        at com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=161
        at com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26

The line that causes the exception is this:

firstByte = in.read();

I am reading on a separate thread. I experienced the same error when I sent requests and tried to read them using the same server. The server is a simple echo server, nothing complex.

P.S. I know that the way the code is written looks like C#, but it is Java, I find it easier to read and follow this way.

Thanks.

A: 

The first thing I see is that you're mis-using available(). It most likely doesn't do what you hope it does.

available() returns an estimate. Its JavaDoc goes on to explicitly state this:

It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

It can very well just return 0, in which case you allocate a buffer of size 0 and try to read into that.

In a conforming implementation that should just return immediately and not read anything, but you could easily trigger a bug in a less-than-perfect implementation with that.

Joachim Sauer
But if there where 0 bytes available, wouldn't the Read method return -1?
npinti
The one in the first line? It's possible that there's only a single byte available.
Joachim Sauer
I understand. I was thinking of making a fixed size buffer, how ever, since this is just like some sort of dummy example, I copied everything from the book so that I can see how it works first. Thanks for pointing it out for me though :)
npinti
A simple way of having a fixed array is to make sure that the first four bytes that is in the stream is for the size of the data to come. After reading those four bytes and calculating the size you can make your byte array. Doesn't have to be a full four-bytes of course; depends on your needs.
Wex
Thanks for the tips guys, how ever, I would appreciate if you do not deviate from the question I asked first.
npinti
It would return -1; but the available() method still can't be trusted to give you the right value. There may be bytes available in the stream but available() returns 0. Basically; don't use the available() method.
Wex
I won't.Anyways, it seems that this is some sort of bug. I am current;y using AVG-Free and have removed/re-activated the firewall, but still no success.http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6804098
npinti
A: 

This example seems to be working: http://www.java-samples.com/j2me/socket-connection-free-j2me-sample-program.htm

Could it be that the problem was that I was implementing the client as a class called by the midlet?

npinti