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: прием/отправка бинарных данных через сокет
Возможно ли открытие одновременно более одного соединения?
|
Часовой пояс GMT +4, время: 02:20. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot