Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
Lib_binsock - библиотека для работы с сокетами в трех режимах:
-побайтно(прием/передача) -прием/передача массивов бинарных данных -InputStream(Resource) Обновление. В версии 1.1 добавлена функция flush для немедленной отправки данных Библиотека содержит следующие функции: procedure debug_register(idx:integer); Устанавливает библиотеке идентификатор, который будет передаваться в обработчик ошибок (о нем ниже) в случае возникновения исключительной ситуации(Exception). procedure enable_debug(flag:integer); Включает/отключает режим отладки. flag = 1 - включить flag = -1 - выключить По умолчанию отладка отключена. Если отладка включена, то в случае возникновения ошибки вызывается процедура-обработчик, определенная в главной программе, например: PHP код:
int ERR_OPENERROR = 0; - ошибка открытия сокета int ERR_CLOSEERROR = 1; - ошибка закрытия сокета int ERR_AVAILERROR = 2; - ошибка при определении размера буфера int ERR_READERROR = 3; - ошибка получения данных int ERR_WRITEERROR = 4; - ошибка отправки данных Внимание! В случае, если отладка включена, обработчик должен присутствовать обязательно, иначе возможен сбой в работе мидлета; если отладка отключена, обработчик объявлять не обязательно. function open(url:string):integer; Открывает соединение с адресом url. Формат url стандартный: socket://url:port Возвращает 1 в случае успеха, иначе возвращает -1 и передает в обработчик сообщение об ошибке ERR_OPENERROR. procedure close; Закрывает соединение. В случае неудачи передает в обработчик сообщение об ошибке ERR_CLOSEERROR. function available:integer; Возвращает размер доступных для приема данных. В случае неудачи возвращает -1 и передает в обработчик сообщение об ошибке ERR_AVAILERROR. function read_byte:integer; Возвращает следующий байт данных из буфера приема, в случае неудачи возвращает -1 и передает в обработчик сообщение об ошибке ERR_READERROR. function write_byte(data:integer):integer; Записывает в буфер передачи байт data. Возвращает 1 в случае успеха, иначе возвращает -1 и передает ошибку ERR_WRITEERROR. function get_in_stream:resource; Возвращает поток resource для подключения. function write_bin(data:string):integer; Записывает массив байт data в поток передачи. Возвращает 1 в случае успеха, иначе возвращает -1 и передает ошибку ERR_WRITEERROR. function read_bin(len:integer):string; Возвращает массив байт из входящего потока. В случае неудачи возвращает null и передает в обработчик сообщение ERR_READERROR. function rx_count:integer; Возвращает количество принятых данных. function tx_count:integer; Возвращает размер принятых данных. function flush:integer; c версии 1.1 Инициирует немедленную отправку данных на сервер Возвращает 1 в случае успеха, иначе возвращает -1 и передает в обработчик сообщение об ошибке ERR_FLUSHERROR. Внимание! --------- Библиотека требует доступа к сети Проверено на Motorola L9. Отправку данных проверить не смог, но должно работать. P.S. Предлагаю всем разработчикам в своих новых библиотеках (еще лучше и старые переделать) использовать такой же принцип обработки ошибок. Чуть позже опишу принцип подробнее. Основная идея состоит в том, чтобы использовать общий обработчик для обработки ошибок от всех библиотек. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
ViNT, спасибо за либу! Весьма полезна.
Но в процессе тестирования на реальных телефонах обнаружилось следующее: 1. Даже если не делать обработчик ошибок, всё равно на некоторых самсунгах может не запускаться. И через обфускатор proguard не проходит. Если создать хотя бы пустую процедуру onerror, то всё ОК. Надеюсь, эта информация пригодится тем, кто будет использовать данную либу. 2. Приём данных я делаю примерно так: PHP код:
Я так понял, что при загрузке сначала заполняется некий буфер, а потом уже из него можно скачивать в бинарный массив. Подобный цикл while..end понадобился, поскольку размер буфера значительно меньше размера реально скачиваемого с сервера контента. На эмуляторе kEmulator переменная count, отображающая binsock.available, принимает максимальное значение 8192. То есть когда я скачиваю с сервера 20 кб данных, цикл проходит 3 раза. Но бинарная картинка, скачанная таким образом, нормально собирается и отображается на эмуляторе. На мобильниках всё не так радужно. Например, на Samsung E-200 размер буфера всего 512 байт. Текстовый контент в приведённом мной выше цикле скачивается и собирается нормально, а вот картинка - нет, приходит битая. Может, сможешь что-нибудь посоветовать? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Спасибо за подробный баг-репорт, буду разбираться.
На счет некорректного приема картинки - надо бы сохранить данные в файл и сравнить с оригиналом, может станет понятно, в чем дело. По поводу размера буфера - посмотрю, что по этому поводу написано в доках. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
а можно примерчит отправки скажем текста
на определённый айпишник, через udp |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Работает нормально, но при проверке на современных телефонах (SE C510 и некоторые Nokia) -не отправляет данные сразу. В процессе разбора полетов выяснилось-телефоны упорно буферизируют данные на отправку. Вылечилось добавлением
public static int write_byte(int data){ tx++; try{ os.write(data); os.flush(); <-----Вот этого return 1; }catch(Exception e){ err(e, ERR_WRITEERROR, "Error writing byte to stream"); return -1; } } public static int write_bin(String data){ byte d[] = data.getBytes(); tx = tx+d.length; try{ os.write(d); os.flush(); <-----и этого }catch(Exception e){ err(e, ERR_WRITEERROR, "Error writing binary to stream"); return -1;} return 1; } |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Да. FLUSH нужно делать обязательно.
На любых телефонах. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Добавил функцию flush
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
добрый день
спасибо за либу, пользую, работает отлично. есть вопрос: присылаю с сервера (delphi 2007, ServerSocket) текст с русскими буквами: тел. НОКИА: текст в ANSI: read_bin возвращает в строке символы ANSI, читаю посимвольно, преобразую в UTF8 - вопросов нет. текст в UTF8: русские буквы приходят по 2 байта (как и положено) тел. LG: текст в ANSI: read_bin возвращает только часть строки ДО первой русской буквы текст в UTF8: принимает на ура, даже преобразовывать ничего не надо. ВОПРОС каким образом можно оптимально заставить оба тел работать? сам я решение предполагаю, и не одно, но они мне не нравяться. LG при получении бинарного потока корректно распознает в нем русские буквы при копировании в строку, нокиа же, просто раскладывает - в каждый символ один байт. буду признателен всем ответившим. привожу свою функцию для преобразования данных из сокета в utf8 с русскими символами, может пригодиться кому нибудь. (функция фильтрует управляющие символы. этой же функцией можно читать русский текст из RecordStore) Код:
function scr_frBIN(s: string): string; // (from BIN, ANSI to UTF) |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Просто режет строку, в обработчик ошибок ничего не сваливается, мидлет не зависает? Вообще, если режет символы даже в бинарном режиме, то вряд ли что-то модно сделать. Хотя, надо посмотреть, может и есть решение.
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
провел тест на LG ( gw300 ):
binsock.debug_register(0); binsock.enable_debug(-1); ansi: отправил: 123фф123 на тел:123? ( len = 4 ) utf-8: отправил: 123фф123 на тел: 123фф123 ( len = 8 ) binsock.debug_register(1); binsock.enable_debug(1); результат тот же, ошибок нет. после получения русских "вопросиков" мидлет продолжает работать. вот исходник теста: (в первом тесте процедуры onerror не было) Код:
program testscr; Код:
procedure TForm1.Button1Click(Sender: TObject); функция binsock.read_byte возвращает именно байты. если пришел ansi - получим именно их коды, utf - по два байта на каждую русскую букву. то есть засада в функции binsock.read_bin() - мне кажется, когда присваивается результат, NOKIA и LG воспринимают это по-разному: нокиа строго раскладывает побайтно, lg в этом потоке бинарных данных рассматривает utf8 символы и преобразует находу. можно ли и NOKIA заставить "распознавать" строку UTF-8 ? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Совершенно непонятно, в чем дело. Скорее всего, какие-то внутренние особенности реализации обработки данных. Не думаю, что с этим можно что-то сделать.
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
1. На Delphi : Перевожу русские буквы в base64, и отправляю в сокет ...Socket.Connections[i].SendText(AnsiToBase64('ваш текст' + '@')), где например @ --- дополнительно обозначаю конец текста PHP код:
EncodeBase64 : PHP код:
2. На мобильном клиенте Считываю данные, PHP код:
PHP код:
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Возможно ли открытие одновременно более одного соединения?
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
В данной версии нет, но в принципе возможно. Если актуально - может найду время дописать.
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Очень актуально )
Думаю, за это буду признателен не только я. Библиотека хорошо себя зарекомендовала в работе, но поддержки нескольких соединений не хватает. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
Собрал тестовый вариант библиотеки для работы с несколькими соединениями, чисто для проверки концепции. Работа отличается только тем, что перед началом работы с функциями библиотеки нужно вызвать метод binsock3.init(int cnt);, где cnt - требуемое количество подключений. Также, каждая функция работы с соединением (т.е. все функции, кроме отладочных) имеет еще один (последний) параметр (кроме указанных в документации), который определяет индекс подключения, к которому идет обращение.
Библиотеку пока не протестировал, поскольку не на чем, а на эмуляторе не работает (это не глюк библиотеки, поскольку старая версия также не работает, видимо, система не дает эмулятору доступ в сеть). И есть еще один момент - возможно, операции с разными соединениями придется разносить в разные потоки, хотя может и так будет работать. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Отличная новость )
Протестирую и отпишусь. Кстати предыдущая версия библиотеки у меня работает на эмуляторе SJBoy. Только нужно добавить в исключения файрволлу. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
ViNT, в описании указано, что read_bin возвращает массив байт из входящего потока или null в случае ошибки.
В MP константы null не зарезервировано. Как интерпретировать это значение? - как пустую строку? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
P.S. Забыл тогда отписаться про либу с несколькими подключениями - при тесте проблем не возникало.
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Я пока использую такую обертку:
Код:
function ReadData(DataLength: Integer): String; Может так и сделать? - в случае ошибки возвращать пустую строку и ввести запрет на вызов чтения данных нулевой длины? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
Прицепляю библиотеку, которую использую
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
В принципе, если вариант с возвращением пустой строки устраивает - выкладываю пересобранную версию. Отличается только тем, что из read_bin возвращает пустую строку вместо null. Хотя, надо будет подумать над более удобным решением.
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вполне устраивает. Спасибо
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
ViNT, важный вопрос:
должны ли функции binsock.available и binsock.read_bin возвращать ошибки и выбрасывать эксепшны, если соединение было потеряно ранее (закрыто сервером или пропала сеть)? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Декомпилировал класс. Насколько я могу судить, в binsock.available, если соединение ранее пропало (и соотв. inpustream уже нет), т.е. is == null, то функция будет возвращать 0, будто все норм:
PHP код:
--- Я до этого с Java совсем не работал - не подскажите как компиллить классы для j2me? какие пакеты нужны и т.д. Главным образом интересуют зависимости для данной библиотеки. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
В этом случае is не будет равен null (он будет по прежнему указывать на объект потока, наличие которого не зависит от состояния соединения), а будет сгенерирован IOException, который будет интерпретирован блоком try...catch как ERR_AVAILERROR.
Библиотеки компилить проще всего в NetBeans, единственный момент - в новых версиях у них там какая-то проблема с подключением J2ME, я решал ручным указанием пути к J2ME WTK (хотя обычно он не нужен). Можно компилить в самом WTK, но это неудобно. Конкретно эта библиотека использует только стандартные пакеты J2ME. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
А в каких случаях is станет null ? для чего эта проверка?
--------------- Нет нетбинса, но есть еклипс. Попробовал скачать eclipse-me-sdk-plugins-uc.zip отсюда http://www.oracle.com/technetwork/ja...sdk/index.html но не встает. --- пробую так же через консоль: Код:
C:\Program Files\Java\jdk1.7.0_09\bin\Java_ME_platform_SDK_3.4>C:\PROGRA~1\Java\ Не могли бы Вы сейчас скомпилировать этот файл (прикладываю в архиве)? хотелось бы кое-что проверить - какая-то проблема последнее время странная. И дело то ли на сервере, то ли на клиенте - непонятно. ---- A с компиляцией уже завтра тогда буду разбираться на свежую голову ) |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
Видимо нужно прописать классы J2ME в classpath, может еще какие-то ключи указать, точно не помню - уже очень давно не компилил через консоль.
null может быть в том случае, если соединение не было открыто (не вызывался метод open()), либо было закрыто (вызван метод close()). На самом деле да, подход не совсем верный - в таком случае стоило бы тоже выкидывать ошибку типа "соединение закрыто", но я по каким-то причинам этого делать не стал, возложив, фактически, контроль состояния библиотеки на программиста(фактически, есть только защита от ошибки, но вот отладку это только усложняет). |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Спасибо. Сейчас буду пробовать - если что - отпишусь в теме
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
В общем поставил NetBeans 7.3, установил JDK (jdk-7u45-windows-i586.exe), установил J2ME SDK (oracle-jmesdk-3-4-rr-win32-bin.exe), плагины для IDE (oracle-jmesdk-3-4-rr-nb-plugins.zip). Все компиллится, все зависимости видит, но class потом не работает ( - программа сразу завершается при любом обращении к классу.
Так же непонятен способ подключения "M" - создал класс в пакете, добавил метод - так нужно? Мне нужно расширить open параметрами KeepAlive и Delay: Код:
public static int open(String url, int Nagle, int KeepAlive){ Цитата:
Цитата:
И подскажи, что делать с классом M ? Как вообще называется подобный механизм? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Кстати, кто будет разбираться - ссылка по теме
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Вложений: 1
Класс M.class это стандартный класс MP, через него можно обращаться к функциям ввода-вывода. Чтобы работать с ним, нужно поместить его исходник в пакет по умолчанию проекта (там же должны находиться и библиотеки).
Дальше в нем можно определять нужные методы (вернее их "заглушки", поскольку сам скомпиленный класс использоваться не будет). Вариант класса, с которым компилится эта библиотека лежит в архиве. Класс может не работать, если его не оттуда взять. Брать готовый класс нужно из build/preverified, тогда должен работать. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
ViNt, спасибо. Действительно - взял класс из папки preverified и все заработало.
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Кто будет использовать параметр KeepAlive - обратите внимание, что его нужно ставить не единицу, а именно значение в секундах через, которое требуется проверять соединение. Это насколько я могу судить по сниферу.
Вот пример подобного использования (правда к комментах): http://jimm-fork.googlecode.com/svn/...TcpSocket.java Если я не прав - поправьте меня. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Как HTTPConnection преобразует URL в IP ?
Как это можно посмотреть? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
напишите пожалуйста пример как соединится и загрузить файл в программу как ресурс
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
PHP код:
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
А как прописать параметр для binsock.open? Можно пример к какому-нить файлу? У меня ошибку подключения всегда выдает
|
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Цитата:
Код:
http://forum.boolean.name:80/showthread.php?t=8960&page=3 |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Допустим возникло исключение, управление передалось в обработчик исключения, там мы его обработали...
куда после этого перейдет управление в программе? На следующий шаг после инструкции, вызвавшей исключение или куда? |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
За пределы блока catch, либо в блок finally, если он объявлен. На следующий шаг после инструкции, вызвавшей исключение, уже никак не попадёшь (разве что в каких-то языках при помощи goto).
Два года пытаешься разобраться? Вот это упорство. |
Ответ: Lib_binsock: прием/отправка бинарных данных через сокет
Иногда все мы возвращаемся к заброшенным проектам:)
|
Часовой пояс GMT +4, время: 15:01. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot