MIDP 2.0 TCP-клиент

Я пытаюсь разработать TCP-клиент, который работает на мобильных устройствах с использованием MIDP 2.0 и CLDC 1.1. Я пробую образец кода, и у меня возникла следующая проблема:

Я получаю странное исключение, когда пытаюсь прочитать данные обратно (из мидлета).

Это мой код:

            //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();

Это исключение, которое я получаю:

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

Строка, вызывающая исключение, следующая:

firstByte = in.read();

Читаю в отдельной ветке. У меня возникла такая же ошибка, когда я отправил запросы и попытался их прочитать с помощью того же сервера. Сервер - это простой эхо-сервер, ничего сложного.

P.S. Я знаю, что код написан как C #, но это Java, мне легче читать и следовать этому пути.

Спасибо.


person npinti    schedule 19.02.2010    source источник
comment
Кстати, какая часть, по вашему мнению, похожа на C #? Я этого не вижу.   -  person Joachim Sauer    schedule 19.02.2010
comment
Я имею в виду то, как я поставил скобки и отступы.   -  person npinti    schedule 19.02.2010


Ответы (2)


Первое, что я вижу, это то, что вы неправильно используете available(). Скорее всего, он не делает то, на что вы надеетесь.

available() возвращает оценку . В его JavaDoc прямо говорится об этом:

Никогда не правильно использовать возвращаемое значение этого метода для выделения буфера, предназначенного для хранения всех данных в этом потоке.

Он вполне может просто вернуть 0, и в этом случае вы выделяете буфер размером 0 и пытаетесь прочитать в него.

В соответствующей реализации, которая должна немедленно возвращаться и ничего не читать, но с этим вы можете легко вызвать ошибку в неидеальной реализации.

person Joachim Sauer    schedule 19.02.2010
comment
Но если бы там было 0 байтов, не вернет ли метод Read -1? - person npinti; 19.02.2010
comment
Тот, что в первой строке? Возможно, доступен только один байт. - person Joachim Sauer; 19.02.2010
comment
Я понимаю. Я думал о создании буфера фиксированного размера, однако, поскольку это как своего рода фиктивный пример, я скопировал все из книги, чтобы сначала увидеть, как это работает. Спасибо, что указали мне на это :) - person npinti; 19.02.2010
comment
Простой способ иметь фиксированный массив - убедиться, что первые четыре байта в потоке соответствуют размеру будущих данных. После прочтения этих четырех байтов и расчета размера вы можете создать свой байтовый массив. Конечно, не обязательно должно быть четыре байта; зависит от ваших потребностей. - person Wex; 19.02.2010
comment
Спасибо за советы, ребята, но я был бы признателен, если вы не отклонитесь от вопроса, который я задал первым. - person npinti; 19.02.2010
comment
Он вернет -1; но нельзя доверять методу available (), который даст вам правильное значение. В потоке могут быть байты, но available () возвращает 0. В основном; не используйте метод available (). - person Wex; 19.02.2010
comment
Я не буду. В любом случае, похоже, что это какая-то ошибка. Я использую AVG-Free и удалил / повторно активировал брандмауэр, но все равно безуспешно. bugs.sun.com/bugdatabase/view_bug.do?bug_id=6804098 - person npinti; 19.02.2010

Кажется, этот пример работает: http://www.java-samples.com/j2me/socket-connection-free-j2me-sample-program.htm

Может быть, проблема заключалась в том, что я реализовывал клиента как класс, вызываемый мидлетом?

person npinti    schedule 19.02.2010