![]() |
Модераторы: javastic, AntonSaburov |
![]() ![]() ![]() |
|
YuraDoc |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 1.4.2006 Где: Zhytomir, Ukraine Репутация: нет Всего: нет |
У меня есть сокетное соединение между компьютером и мобильным телефоном.
Создан некий протокол обмена сообщениями. Задача: необходимо передать информацию в мобильное устройство, а именно сообщение с описанием файла, а затем сам файл. При этом чтобы я смог разделить их (сообщение, файл). Сообщение передается в виде строки, а файл в виде массива байт. Заранее благодарен за ответ. |
|||
|
||||
eugine_s |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 581 Регистрация: 14.11.2007 Где: Киев Репутация: 17 Всего: 17 |
Сообщение - это хоть и строка, но передается тоже в качестве набора байт....
Поэтому можно передавать все байтами.
и отправлять в это на мобильный в таком порядке: 1. один байт равный msgDataSize 2. N байт - строка сообщения (N = msgDataSize); 3. imgData Мобильный эти байты обрабатывает вот так: 1. Читает первый байт. Получает N. 2. Читает N следующих байт и из них строит строку. String str = new String(byte data[]); 3. Читает все остальные байты - байты картинки. Я правильно понял твой вопрос? |
|||
|
||||
YuraDoc |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 1.4.2006 Где: Zhytomir, Ukraine Репутация: нет Всего: нет |
Да ты правильно меня понял.
Но у меня прикол в том что сервер обрабатывает сообщения к которым прикреплен "\n" с помощью BufferedReader. Было бы неплохо реализовать нечто подобное и на мобильнике. Т. е. обойти передачу размера сообщений и т.д. |
|||
|
||||
Dummy |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 21.5.2007 Репутация: 7 Всего: 19 |
Самое высокоуровневое для работы с потоками, что есть в CLDC (соответственно, и в MIDP), - это DataInputStream / DataOutputStream, которые позволяют читать / писать строки через readUTF / writeUTF. Тогда для передачи на телефон можно делать примерно следующее:
Соответственно, на стороне телефона читать примерно так:
Неудобный момент здесь в том, что readUTF / writeUTF должны работать в паре, иначе возможны неудобства с чтением модифицированного UTF, в который преобразуется передаваемая строка. Это сообщение отредактировал(а) Dummy - 5.5.2008, 14:32 |
||||
|
|||||
YuraDoc |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 1.4.2006 Где: Zhytomir, Ukraine Репутация: нет Всего: нет |
Спасибо всем. Проблема решена так: сообщение читалось побайтно, находился '\n', затем DataInputStream.readFully(buf) читает файл.
И кстати ничего плохого нет в том что я читаю методом DataInputStream.readFully(buf) файл? У меня в проге паралельно читаются файлы на мобилу. А также, реализовано ли параллельное чтение файла в MIDP? Это сообщение отредактировал(а) YuraDoc - 5.5.2008, 18:52 |
|||
|
||||
Dummy |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 21.5.2007 Репутация: 7 Всего: 19 |
Ну, концептуально в readFully() нет особо плохого ничего, за исключением того, что это блокирующий вызов, а значит, ты подвешиваешь поток исполнения на время, пропорциональное размеру читаемых данных. В твоем случае это может быть весьма значительно. Это означает, что этот метод не стоит вызывать из GUI-callback-функций, таких как Displayable.commandAction, обработчиков типа Canvas.keyPressed, Canvas.keyReleased, Canvas.hideNotify, Canvas.showNotify и другие, вызываемые из контекстов системных потоков, иначе просто подвесишь графическую систему и обработку событий JVM на весь период чтения. Не все JVM умеют умно отдавать управление системе в заданные интервалы. А это значит, что JVM просто может не отдать управление ОС до тех пор, пока не закончит чтение, даже в том случае, если ты пустишь чтение данных в отдельном потоке.
Кроме того, ты же, вроде, сам говорил, что не хочешь возиться с передачей длин сообщений. А с использованием readFully это неизбежно, т. к. ты должен выделить буфер соответствующего размера и подать его на вход этой функции, чтобы считать все разом - тебе ведь это нужно? Если ты выберешь буфер фиксированного размера, то, возможно, придется вызывать readFully() несколько раз, чтобы считать все данные без остатка. Но в таком случае лучше выбрать обычный read(), который честно считает столько данных, сколько получится, и может вернуть управление, даже если данные в потоке еще есть, а буфер заполнен не целиком. Лично мне не совсем ясно, что такое "параллельное чтение файла". Чтение данных от разных файлов из нескольких сокетов? Так это пожалуйста, ограничение здесь, в основном, исходит от платформы - на количество одновременно открытых сокетов, например. Читать из одного потока данных несколькими тредами? Тогда непонятно, какой в этом смысл. |
|||
|
||||
Majesty |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 98 Регистрация: 20.3.2005 Где: Almaty, Kazakhsta n Репутация: нет Всего: нет |
Кстати, к вопросу о блокирующих вызовах
![]() Не мог ли бы кто-нибудь привести пример правильного пользования такими вызовами? Я пишу одно приложение, работающее с камерой и, соответственно, использующее такой вызов. Как ни пытался, а отделить его от гуя у меня мозгов не хватает. То есть, я выкидываю капчу с камеры в отдельный поток, но вызывать-то её всё равно приходится из commandAction'а ![]() Телефон (SE K700) с этим нормально справляется, а вот WTK'шный эмулятор безнадёжно виснет. |
|||
|
||||
YuraDoc |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 1.4.2006 Где: Zhytomir, Ukraine Репутация: нет Всего: нет |
readFully() я вызываю в отдельном потоке. Выходит, что это не помогает я так понял.
Как только я считал этим методом я с помощью паттерна Observer уведомляю GUI о том, что пришли данные.
Размер данных на входе я узнаю с помощью метода in.available() (или это не верно?). "параллельное чтение файла" - под этим я имел ввиду, когда несколько сокетов читает и передает один файл. Работает ли это в большинстве случаев? |
|||
|
||||
Dummy |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 21.5.2007 Репутация: 7 Всего: 19 |
Использовать InputStream.available() для выяснения размера передаваемых данных не стоит. При потоковой передаче данных фишка как раз в том, что размер итоговых данных в общем случае неизвестен. По спецификации MIDP этот метод возвращает количество байт, которые на момент вызова можно считать из потока без блокировки, т. е. это некоторый объем кэшированных данных. Например, если ты используешь какой-нибудь буферизованный поток, читающий из сети, то он просто может считывать данные с упреждением, но это не означает, что в кэш будут считаны все данные разом. Для каких-то типов потоков (например, поток из файла) available теоретически может вернуть полный размер данных (опять же зависит от реализации), но далеко не всегда.
Я не хочу сказать, что это не помогает. Просто придерживаюсь мнения, что в твоей ситуации применение readFully() не оправдано. Добавлено через 5 минут и 54 секунды Majesty,
Можешь привести пример кода для твоей ситуации? У меня подозрения есть, с чем это может быть связано. Это сообщение отредактировал(а) Dummy - 6.5.2008, 13:24 |
||||||
|
|||||||
YuraDoc |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 1.4.2006 Где: Zhytomir, Ukraine Репутация: нет Всего: нет |
Неужеле никто не знает, можно ли обращатся к файлу на мобиле одновременно, с разных сокетов, в разных потоках?
|
|||
|
||||
Dummy |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 21.5.2007 Репутация: 7 Всего: 19 |
Я не думаю, что кто-то здесь тебе даст универсальный ответ. Если реализация JSR-75 разрешает тебе открыть несколько потоков чтения из одного файла, то ради Бога. Если нет - получишь IOException на попытке открыть второй поток из файла. Все зависит от платформы и от реализации JVM - можно ли на ней несколько раз открыть файл в режиме чтения. Посмотри, как ведет себя WTK в такой ситуации. Потом возьми реальные железки и пробуй. В любом случае твой код должен правильно обрабатывать ситуацию, когда можно открыть не более одного потока из файла. Это сообщение отредактировал(а) Dummy - 6.5.2008, 14:58 |
|||
|
||||
DarK__AngeL |
|
||||
Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 7.12.2007 Репутация: нет Всего: нет |
проще завести перменную:
а потом уже её использовать для всех потоков Добавлено через 1 минуту и 51 секунду у меня же такой вопрос на эту тему: как вообще сохранить файл, который приходит в байтовом массиве? то есть как узнать расширение, да и вообще, как происходит сохранение файлов в J2ME? |
||||
|
|||||
Dummy |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 21.5.2007 Репутация: 7 Всего: 19 |
Такой подход требует:
Либо в RMS, либо, если в телефоне есть поддержка JSR-75, прямо-таки в файл. Об этом на форуме информации туча. Да и сам JSR-75 - довольно простой для понимания на базовом уровне документ.
Данные, которые из потока читаются, в строгом смысле "файлом" не являются, а станут им только после того, как будут сохранены в файловой системе телефона. Именно тогда они получат имя и, возможно, расширение. Один вариант - придумать свой протокол при передаче через сокеты - например, передавать имя файла вначале, а затем его данные. Еще вариант - использование OBEX, но TCP/IP OBEX может и не поддерживаться на телефоне. Это сообщение отредактировал(а) Dummy - 12.5.2008, 15:00 |
||||||
|
|||||||
DarK__AngeL |
|
|||
Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 7.12.2007 Репутация: нет Всего: нет |
насчёт InputStream file: а копировать эту переменную для каждого потока не выход?
|
|||
|
||||
Dummy |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 263 Регистрация: 21.5.2007 Репутация: 7 Всего: 19 |
Нет, не выход. Реальный поток данных все равно один. Так что если несколько потоков будут читать из него попеременно, то в результате каждый из них просто получит какие-то обрывки данных, причем из разных мест передаваемого файла.
|
|||
|
||||
![]() ![]() ![]() |
FAQ раздела лежит здесь! |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java ME (J2ME) | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |