Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java ME (J2ME) > DataInputStream


Автор: VKoresh 3.7.2007, 14:59
 Сделал вот так:
Код


public SocketConnection sc;                        
public SocketConnection listener;    

public void run()
    {
        int c = 0;
        String S;

        try
        {
            sc = (SocketConnection)Connector.open("socket://" + (TFIP.getString()) + ":" + (TFPort.getString()));
            listener = (SocketConnection)Connector.open("socket://:5555");
            DataInputStream listener = sc.openDataInputStream();        
            DataOutputStream os = sc.openDataOutputStream();                
            StringBuffer sb = new StringBuffer();
        
            while (((c = is.read()) != '\n') && (c != -1))
            {            
                sb.append((char)c);
            }                                            
                            
            // дальше отсылает строку...                
            
        }
        catch (IOException x)                                        
        {
            x.printStackTrace();
        }        
     }




Дело в том, что мне надо чтобы приложение не только отсылало строки но и принимало их. Отсылает на ура,а вот слушать порт и принимать не хочет. smile 
 На строке

listener = (SocketConnection)Connector.open("socket://:5555");

выдает java.io.IOException: ServerSocket Open 
Помогите, пожалйста! 

Автор: W0LF 3.7.2007, 15:19
а ты посмотри в сторону 
Код

javax.microedition.io
Interface ServerSocketConnection


Добавлено через 3 минуты и 51 секунду
Посмотри в WTK там пример есть очень простой.
Цитата

\WTK22\apps\NetworkDemo\

Автор: VKoresh 3.7.2007, 16:21
Смотрел, не помогло, Горнакова и Пирумяна тоже читал, и тоже не помогло. smile  smile  smile 
Обидно, что даже компилится без ошибок... smile  

Автор: VKoresh 3.7.2007, 16:38
 smile Где бубны продают?

Автор: AntonSaburov 3.7.2007, 16:41
А ты уверен, что этот порт свободен ? В смысле - 5555. Мож кто на нем висит постоянно ?

Автор: Dancer 3.7.2007, 16:54
дык он сам же на нём и висит скорее всего smile

вот этот кусок кода очень не понятен!!!! (почему одно и то же название переменно фигурирует, перекрытие имён происходит)

listener = (SocketConnection)Connector.open("socket://:5555");
            DataInputStream listener = sc.openDataInputStream();

Добавлено через 8 минут и 29 секунд
наверное должно быть так smile
Код

            sc = (SocketConnection)Connector.open("socket://" + (TFIP.getString()) + ":" + (TFPort.getString()));
            listener = (SocketConnection)Connector.open("socket://:5555");
            DataInputStream is = sc.openDataInputStream();        
            DataOutputStream os = listener.openDataOutputStream();                
            StringBuffer sb = new StringBuffer();

Автор: VKoresh 3.7.2007, 17:07
Добавлено @ 17:09
AntonSaburov
Цитата

А ты уверен, что этот порт свободен ? В смысле - 5555. Мож кто на нем висит постоянно ? 
, свободен как птица в полете smile

Добавлено @ 17:19
Dancer, сделал 
Код

public void run()
    {
        int c = 0;
        String S;

        try
        {
            sc = (SocketConnection)Connector.open("socket://" + (TFIP.getString()) + ":" + (TFPort.getString()));
            os = sc.openDataOutputStream();            
            listener = (SocketConnection)Connector.open("socket://:5555");
            DataInputStream is = sc.openDataInputStream();
            DataOutputStream os = listener.openDataOutputStream();
            StringBuffer sb = new StringBuffer();

            while ((c = is.read()) != -1)
            {
                sb.append((char)c);
            }
            System.out.println(sb.toString());
    
            //не важно...
            
        }
        catch (IOException x)                                        
        {
            x.printStackTrace();
        }        
     }

все как ты и говорил... Все та же проблемма -  На строке

listener = (SocketConnection)Connector.open("socket://:5555");

выдает java.io.IOException: ServerSocket Open 


Автор: Dancer 4.7.2007, 09:39
Ну давай всё с самого начала. (кстати на другом форуме это то же ты? Malkav кажется - или мне и туда и сюда отвечать нужно если вы два разных человека?)

1. Расскажи что ты хочешь сделать?
2. "Кто" такой сервер с которого ты что-то читаешь?
3. Есть ли возможность что-то посылать в определённый порт этого сервера и видеть, что он это принял и увидеть его реакцию?

=====================================
Я не понимаю, для чего тебе на девайсе спецом заводить порт для прослушки, возможно ты просто немного не в ту сторону рубишься smile
Если ты заводишь на "своём" телефоне порт, для того чтобы тебе кто-то на него что-то присылал (с друго телефона, с тырнета и т.д.) тебе нужно пользовать другой интерфейс для его создания. 

ServerSocketConnection ssc = (ServerSocketConnection)Connector.open("socket://:9677");
Это будет означать, что ты на своём телефоне слушаешь порт 9677, и всё что на него поступит, ты можешь обработать.
Но для того чтобы в этот порт что-то пришло, нужно чтобы кто-то отправил тебе какие-либо данные. Это либо другой аппарат, либо с сайта (скриптом). Тебе нужно получить IP адрес твоего аппарата, и по этому адресу он будет доступен "клиентам"
чтобы узнать IP адрес, который выдаётся динамически оператором, после регистрации сервака ssc коннекшена можно вызвать метод getLocalAddress() на объекте ssc.
Для работы с ssc (чтение/запись) нам понадобится SocketConnection oбъект, мы его получаем через специальный метод:
SocketConnection server = (SocketConnection) ssc.acceptAndOpen();
ну и далее уже по известной схеме, получаем стримы для чтения/записи
InputStream serverIS = server.openInputStream();
OutputStream serverOS = server.openOutputStream();



Если же ты работаешь с каким-то серваком и тебе в него нужно что-то писать (делать какие-то посылки данных на сервер, не только чтение) то делаем это следующим образом, через интерфейс SocketConnection

SocketConnection sc = (SocketConnection) Connector.open("socket://"+IP+":"+PORT); 
IP это обязательное поле!!!!
InputStream is = sc.openInputStream(); // для чтения данных с сервера из коннекшена sc
OutputStream os = sc.openOutputStream();// для отправки данных серверу из коннекшена sc
--------------------

Маленькое отступление. Где ты это пытаешься "смотреть" (тестить). Могу предложить простенький вариант.
Подними у себя на локальной машине простенький самописный сервер (можешь посмотреть как это делается в J2SE и работать с серваком на Java), ну или какой нить Apache или что-то в этом роде. Если не Java сервак, то тогда сделай скрипт perl/jsp/asp (или что-то другое, что лучше знаешь) и сиди и слушай этим скриптом порт, и делай какой-нить ответ "PONG", если тебе в этот порт сваливается "PING" и выводи это в лог или на браузерную страницу или ещё как.
То есть, ты этим просто сможешь проверить, что у тебя твой Java клиент на мобиле робит. А клиента запускаешь через WTK регистрируя SocketConnection как Connector.open("socke://127.0.0.1:"+PORT); PORT = это твой зарегенный порт на серваке (Java, Apache и т.д.)

Автор: VKoresh 4.7.2007, 10:53
Dancer, Malkav - это, можно сказать, мое второе Я smile

1) Мой мидлет должен представлять собой клиент, котрый коннектится к серверу и может отсылать ему комманды и ,соответственно им, принимать изображения, звуки, музыку, текст и т.д.
2) Сервер представляет собой прогу на Delphi, которая спит и видит принять откуда-нибудь комманду. Т.е. перманентно ожидает коннекта. По коннекту отсылает соответствующее уведомление, из серии "молодец, я тебя вижу, теперь пришли мне еще комманду че тебе еще переслать".
3) Сервер ведет лог и там отображется что, мол 11:05:59 законнектился Вася Пупкин и т.д. Ответы шлет автоматически. В работе сервака я уверен больше, чем в том что солнце встает на востоке. smile (Может быть потому, что писал его не я smile)
 
Сейчас у меня такой трабл - коннектится просто зашибись, а ответ принять нормально не может...

Код

public void run()
    {
        int c = 0;
        String S;

        try
        {
            // открывет соединение с сервером
            sc = (SocketConnection)Connector.open("socket://" + (TFIP.getString()) + ":" + (TFPort.getString()));
            // открывает исходящий поток 
            os = sc.openDataOutputStream();

                       // os.write и т.д. в общем шлет 

            is = sc.openDataInputStream();        

/*                        
                        listener = (ServerSocketConnection)Connector.open("socket://:5555"); // прослушиватель на 5555 порту
                        // strcon - public StreamConnection
                        strcon = listener.acceptAndOpen();
                        is = strcon.openDataInputStream(); // открывает входящий поток

 // С таким раскладом выдает java.io.IOException: ServerSocket Open
 // на строке listener = (ServerSocketConnection)Connector.open("socket://:5555");

*/
            StringBuffer sb = new StringBuffer();
      
            while (((c = is.read()) != '\n') && (c != -1))
            {          
                sb.append((char)c);
            }
      
            if (c == -1)
            {             
                stop();    // break тут почему-то не становится...
            }
     
            System.out.println("Message received - " + sb.toString());                        
            
        }
        catch (IOException x)                                        
        {
            x.printStackTrace();
        }        
     } 


С таким раскладом принимает один раз...последний smile 
Но, сам понимаешь, такое решение никуда не годится... Вот и начал придумывать себе прослушиватель... smile описанный выше и на другом форуме.
ЗЫ давай уж тут отписываться, а не на другом форуме. Пора прекратить на фиг эту путаницу. smile


 

Автор: VKoresh 4.7.2007, 11:44

Как обрабатывать поступившие данные мне пока не важно. Мне надо чтоб он мог их принимать постоянно...

Автор: W0LF 4.7.2007, 12:30
Цитата

1) Мой мидлет должен представлять собой клиент, котрый коннектится к серверу и может отсылать ему комманды и ,соответственно им, принимать изображения, звуки, музыку, текст и т.д.

Тебе для этого не нужно открывать второе соединение на телефоне.. Когда ты подрубился к серваку - он тебе уже сам может посылать все, что надо. Это ж тебе не хттп - отослал-принял, а соединение всегда открыто.
Цитата

С таким раскладом принимает один раз...последний smile

Ага.. понятно.. все намного проще.. и не надо серверов никаких на телефоне smile
Я ж просил посмотреть на пример из WTK   smile 
Код

public void run() {
        try {
            sc = (SocketConnection) Connector.open("socket://localhost:5000");//тут у тя так же
            si.setText("Connected to server");
            is = sc.openInputStream(); // это тож в принципе как у тебя
            os = sc.openOutputStream(); // и это тож

            // Start the thread for sending messages - see Sender's main
            // comment for explanation
            sender = new Sender(os);

            // Loop forever, receiving data
            //А теперь мы заметили обрамляющий цикл! Сейчас чуть освобожусь и напишу как все работает
            while (true) {
                StringBuffer sb = new StringBuffer();
                int c = 0;

                while (((c = is.read()) != '\n') && (c != -1)) {
                    sb.append((char) c);
                }

                if (c == -1) {
                    break;
                }

                // Display message to user
                si.setText("Message received - " + sb.toString());
            }
            stop();
            si.setText("Connection closed");
            f.removeCommand(sendCommand);
        } catch (ConnectionNotFoundException cnfe) {
            Alert a = new Alert("Client", "Please run Server MIDlet first",
                    null, AlertType.ERROR);
            a.setTimeout(Alert.FOREVER);
            a.setCommandListener(this);
            display.setCurrent(a);
        } catch (IOException ioe) {
            if (!stop) {
                ioe.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 


Автор: VKoresh 4.7.2007, 12:42
Освобождайся, я подождуsmile 

А что касается примера, то впрвх - Бесконечный Цикл?
Код

 while (true)

А ввтрх - У меня большая часть кода как раз оттуда, но с некоторыми доработками..
и втртх -  smile 

Автор: W0LF 4.7.2007, 12:58
Хм, чуть освободилсо smile
Код

public void run() {
        try {
            sc = (SocketConnection) Connector.open("socket://localhost:5000");//тут у тя так же
            si.setText("Connected to server");
            is = sc.openInputStream(); // это тож в принципе как у тебя
            os = sc.openOutputStream(); // и это тож
            // Start the thread for sending messages - see Sender's main
            // comment for explanation

тут все ясно
Код

sender = new Sender(os); 

Тут тож ясно, класс Sender разберем ниже.
Код

// Loop forever, receiving data
            //делаем бесконечный цикл для того, чтоб ловить входящие пакеты
            while (true) {
                StringBuffer sb = new StringBuffer();
                int c = 0;

                //читаем один пакет, если приходит -1, то это разрыв соединения, выходим из цикла
                //в этом примере завершающим символом пакета считается '\n', то есть если прийдет
                // '\n' то тож выходим из цикла
                //Если же сервер ниче не присылает, то на методе is.read() этот поток остановился и
                //А что касается примера, то впрвх - Бесконечный Цикл?
                //бесконечный цикл будет тупо ждать входящего пакета
                while (((c = is.read()) != '\n') && (c != -1)) {
                    sb.append((char) c);
                }
                //если нам все-таки пришел -1, то это разрыв соединения и мы выходим из бесконечного
                //цикла вообще и более не ждем пакетов от энтого сервера
                if (c == -1) {
                    break;
                }

                // Display message to user
                si.setText("Message received - " + sb.toString());
            } 

Sender надо расписывать?

Автор: VKoresh 4.7.2007, 13:04
Цитата

Sender надо расписывать?

Если не затруднит... smile хотя шлет у меня вроде нормально. Но принцип работы в целом интересен мне.

Но получается Бесконечный Цикл выполнится один раз?
К примеру ситуация - отслал-принял-отослал-принял? каждый раз вызывать run? Я правильно понял?

Автор: W0LF 4.7.2007, 16:08
Цитата

К примеру ситуация - отслал-принял-отослал-принял? каждый раз вызывать run? Я правильно понял?

нет, не правильно.. run() - это метод потока. он завершился - поток умер(очень грубо говоря).
Бесконечный цикл ждет пакеты, внутренний цикл - считывает один пакет
Тебе нужно просто запустить поток и все.. далее он будет работать
Sender чуть позже распишу.. реально времени нет :(
Код

client = new Client(this);
client.start(); 

Еще раз говорю :
смотри в пример WTK. просто смотри что и как они делают. smile

Автор: VKoresh 4.7.2007, 16:38
Тогда надо как-то отсылать параллельно с бесконечным циклом?

ЗЫ Пойду еще покурю мануалы  smile 

Автор: W0LF 4.7.2007, 16:46
Цитата

Тогда надо как-то отсылать параллельно с бесконечным циклом?

Да, класс Sender юзает отдельный поток и он же - потокобезопасен(синхронизирован)

Автор: VKoresh 4.7.2007, 16:53
Что-то меня вообще не в ту степь понесло... Получается, что вообще необязательно создавать отдельный класс и поток. Ведь есть InputStream. Проще дописать в CommandAction еще комманду которая будет пересылать что-нибудь. Сейчас сяду пробовать.

Автор: W0LF 5.7.2007, 12:09
тебе нужно почитать про многопоточность

Автор: VKoresh 5.7.2007, 13:17
Сейчас докатился до вот такого:
Код


public void run()
    {
        
        int c = 0;
        String S;
        int av = 0;

        try
        {
            sc = (SocketConnection)Connector.open("socket://" + (TFIP.getString()) + ":" + (TFPort.getString()));
            os = sc.openDataOutputStream();
            is = sc.openDataInputStream();
            

            //os.write и т.д.

            while (true)
            {
                av = is.available();
                if (av > 0)
                {
                    if (sb.length() > 0)
                    {
                        sb.delete(0, sb.length() - 1);
                    }

                    while (av > 0)
                    {
                        c = is.read();
                        av = is.available();
                        System.out.println("av " + av);
                        sb.append((char)c);
                        System.out.println("receiving" + sb.toString());
                    }                

                    System.out.println("Message received - " + sb.toString());
                    // дальше должна быть обработка полученной строки
                }
            }
        }
        catch (IOException x)                                        
        {
            x.printStackTrace();
        }        
     }




Принимает, однако параллельно с этим ничего не может сделать, т.е. не реагирует до тех пор пока все не получит.
Также такой прикол - available возвращает число не больше 25! И еще вопрос можно сделать чтоб он не побайтно считывал а все сразу?
Пробовал read(byte[] b), то ли не понял, то ли.. smile 

ЗЫ W0LF, не кинешь ссылку на какую-то инфу про многопоточность? Великий и Ужасный Гугл меня не понял... :(

Автор: W0LF 5.7.2007, 15:27
http://lib.juga.ru/article/view/166/1/68/

Добавлено через 1 минуту и 8 секунд
А вообще : один топик - один вопрос.

Автор: VKoresh 11.7.2007, 13:29
W0LF, спасибо! с помощью wait и notify реализовал! Такой довольный, хоть джигу пляши smile  

Автор: W0LF 11.7.2007, 13:54
На здоровье smile

Автор: Yelodia 3.2.2010, 21:19
Здравствуйте! Решила не создавать новую тему, а задать вопрос в этой, так как десь обсуждается networkDemo. Сервер написан на дельфи, а клиента запускаю на эмуляторе, программу networkDemo. Код java не правила. Дело в том, что сервер от клиента принимает сообщения нормально, а вот клиент от сервера не принимает. Вернее, может и принимает, но в статусе не выводит, что сообщение получено. Можно было предположить, что с сервером что-то не так, но когда он посылает сообщения, то в окне эмулятора горит индикатор связи, значит, связь все таки есть. А сообщение так и не выводит (или не получает). В чем тут проблема?

Автор: W0LF 4.2.2010, 13:50
Проблема где-то в коде скорее всего
В смысле его надо показать

Автор: Yelodia 9.2.2010, 12:55
Получение сообщения происходит здесь:
Код

        // Loop forever, receiving data
        while (true) {
        StringBuffer sb = new StringBuffer();
        int c = 0;
        while (((c = is.read()) != '\n') && (c != -1)) {
            sb.append((char) c);
        }
        if (c == -1) {
            break;
        }
        // Display message to user
        si.setText("Message received - " + sb.toString());
        }


Но в текстовом поле si полученное сообщение не отображается, а только строка, которая устанавливается при соединении с сервером:
Код

        si.setText("Connected to server on port "+portString);

Вернее, если сервер запускать также через WTK, то все работает нормально. Но нужно, чтобы j2me клиент работал с сервером, написанным на Delphi, с которым имеет место эта проблема.
Код отправки сообщения сервером:
Код

procedure TForm1.BitBtn3Click(Sender: TObject);
     var i: Integer;
    begin
      for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do begin
       ServerSocket1.Socket.Connections[i].SendText(Edit1.Text);
       Application.ProcessMessages;
      end;
      Memo1.Lines.Insert(0,'< '+Edit1.Text);
    end;

Но проблема не в сервере, так как клиент на Delphi сообщения сервера принимает нормально

Автор: Dancer 9.2.2010, 16:04
На форме есть элементы, и если нужно обновить (перерисовать) форму (элементы на форме), после изменения значения этих элементов, то:
  - либо создаём собственную форму и имплементим ItemStateListener
  - либо какой-либо класс имплементит ItemStateListener, а форма должна будет зарегить листенер:
     class MyClass implements ItemStateListener {
......
         Form myForm = new Form();
         myForm.setItemStateListener(this);
         StringItem si = new StringItem("MSG:","unknown...");
         myForm.append(si);
......
         si.setText("Bla-bla-bla");
.......
         public void itemStateChanged(Item item) {
             if(item == si) {
                 Display.setCurrent(myForm); // Display.getDisplay(MIDlet).setCurren(Item);
            }
     }

Автор: Yelodia 9.2.2010, 18:52
Попробовала, не работает. Дело не в изменении объекта Item, так как изначально (то есть с сервером на j2me) работало и без этого обработчика. Изменила код так, что при получении сообщения выводилось уведомление Alert:
Код

        while (true) {
        StringBuffer sb = new StringBuffer();
        int c = 0;
        while (((c = is.read()) != '\n') && (c != -1)) {
            sb.append((char) c);
        }
        if (c == -1) {
            break;
        }

        // Display message to user
           Alert a = new Alert("Client",
            "Message received " + port,
            null, AlertType.INFO);
        a.setTimeout(Alert.FOREVER);
        a.setCommandListener(this);
        display.setCurrent(a);
        }

Нет никакой реакции, получается, что клиент от сервера вообще не принимает сообщения...

Автор: Dancer 9.2.2010, 19:21
Код

ну, хорошо, а вы можете сервак на делфи снабдить трейсами и посмотреть логи?
Чтобы быть реально уверенным, что данные с него действительно были отправленны.
Так как is.read() - это блокирующая операция, и разблокируется она лишь в том случае, как что-то от сервака действительно в этом потоке появиться, ну или будет уничтожен коннекшен со стороны сервера.
Так же есть NetworkMonitor когда запускаете приложение в WTK его можно использовать для дебага и смотреть, как пакеты ходят через сетку.

Автор: Yelodia 9.2.2010, 20:20
Запустила NetworkMonitor, там отправленная сервером строка отображается нормально, думаю, остальное нет смысла делать. 
user posted image
А вот клиент по прежнему не реагирует на событие...

Автор: W0LF 10.2.2010, 00:09
а где после qwerty "\n" ?
Код

(c = is.read()) != '\n') && (c != -1)

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

Автор: Yelodia 10.2.2010, 18:11
Ой... И правда. Как всегда, глупая ошибка. 
W0LF, спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)