Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Socket теряет сообщения (http://www.flasher.ru/forum/showthread.php?t=149048)

PByH 18.01.2011 15:43

Socket теряет сообщения
 
Народ есть проблема - socket теряет сообщения от сервака.
Код AS3:

        public function send(str:String):void {
                        str += ";\n";
                        socket.writeUTFBytes(str);
                        socket.flush();
                        trace("Серверу: ",str)
        }
        private function readResponse():void {
                var i,j,k:int
                    inp_str = socket.readUTFBytes(socket.bytesAvailable);
                trace("Сервер:",inp_str)
                ...
        }

inp_str - переменная типа String объявлена в классе как private, и больше нигде не используется.
функцией send шлются строки примерно в 70 символов раз в 120 мс. При тыке мышкой шлется дополнительная строка (единожды) тем же оъемом.
На сервер все доходит, обрабатывается и уходит ответ, но почему-то не доходит до флешки (как раз тот самый ответ на событие мыши). Вернее, иногда получается, что ответ доходит, а иногда - нет (50 на 50).
Если кто-то сталкивался с подобной проблемой, или есть соображения по этому поводу, то было бы интересно узнать Ваше мнение по поводу решения этой проблемы.

bav 18.01.2011 15:53

Не знаю, когда у вас вызывается функция readResponse(), но судя по сигнатуре, не в ответ на какое-либо событие. Попробуйте подписаться на событие ProgressEvent.SOCKET_DATA.

PByH 18.01.2011 16:04

Цитата:

Попробуйте подписаться на событие ProgressEvent.SOCKET_DATA.
Да, именно на это событие вызывается readResponse.

Jewelz 18.01.2011 16:24

а само событие вызывается или нет? может не во флеше проблема

wvxvw 18.01.2011 17:15

Если в строке есть нуль-байты, то в консоль будет выводиться только до первого такого байта.
А за такие названия переменных я бы руки по самые уши бы отрывал :)

PByH 18.01.2011 18:36

Цитата:

а само событие вызывается или нет? может не во флеше проблема
событие срабатывает, trace выдает то, что пришло в сокет. Но среди пришедших данных нет того самого, нужного ответа.
Цитата:

Если в строке есть нуль-байты, то в консоль будет выводиться только до первого такого байта.
странно. Иногда у меня получается слать на сервер склееные собщения, между которыми стоит "\n", ответ приходит соответствено такой же и в окне trace он отображается с переносом строки, т.е. сообщение НЕ режется по нулевому байту.
З.Ы. не надо мне руки отрывать :) пригодятся еще :)

wvxvw 18.01.2011 19:53

\n = 13
\x00 = 0
почувствуйте разницу.

PByH 18.01.2011 22:46

wvxvw, спасибо за подсказку :)
Появилось подозрение, что сообщения не успевают считываться. Т.е. если одновременно приходит 2 сообщения, и они записываются в байтэррэй сокета (в конце каждого стоит нуль-байт "/x00"), то получается, я могу считать первое сообщение, а остальные пропадают? Как думаете, такое возможно?
И еще, кто-нибудь может подсказать, как считать из ByteArray данные, оказавшиеся за нуль-байтом?

Добавлено через 43 минуты
Исхитрился-таки :) Нашел способ считать инфу за нуль-байтом!
Код AS3:

var st1:String="c\x00def\x00ghi"
var ba:ByteArray= new ByteArray()
ba.writeUTFBytes(st1)
var result_str:String=""
ba.position=0
do{
        result_str+=ba.readUTFBytes(ba.bytesAvailable)+"|"
        ba.position=result_str.length
        trace(result_str)
}while(ba.bytesAvailable!=0)

trace выдает
Цитата:

c|
c|def|
c|def|ghi|
Правда do while жутко не нравится..
Ладно, буду проверять гипотезу о склеивании пришедших сообщений :)

zhoran 19.01.2011 17:03

ну как, в чем дело было?

ChuwY 19.01.2011 18:58

Сокетное соединение не гарантирует того, что ваши сообщения придут именно такими кусками, как вы их отправили.

То есть, если на сервере вы сделали два раза flush(), то это вовсе не значит, что будет именно два события SOCKET_DATA на клиенте. Если передаваемый кусок данных большой, например видео или картинка, то событий будет куча. А если отправить два мелких сообщения подряд они могут прийти на одно событие.

Выход такой -- складываем все пришедшие байты по SOCKET_DATA в буфер, потом анализируем на конец и начало сообщения. То есть есть ли там ЦЕЛОЕ сообщение, если есть -- вычитываем его и обновляем буфер. То есть, например, послали три сообщения, а пришли они в два куска. Считываем полтора с сокета, записываем их в буфер, вычитываем первое из буфера и стираем, оставляя там половину. А со следующего события это все склеивается в буфере и вычитывается. И никаких потерь. Возможно, придется написать некий свой протокол передачи данных. Я использовал определенный формат сообщений. Без символов конца, а с символом начала, кажется, и указанием полной длины сообщения, указанием длины ключа, ключом, указанием длины только лишь передаваемой полезной информации и собственно информации. Что-то в этом роде.

Извините, если немного не в тему.


Часовой пояс GMT +4, время: 04:07.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.