Форум 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=155531)

cremnet 05.05.2011 21:46

Потереные сообщения Socket
 
Есть Socket server, и клиент socket AS3 приложение. Проблема потери сообщений если сервер шлет в подряд более одного сообщения то клиент не получет второе а то и третье. если сообщения отралвлять с задержкой то сообщения доходят.
Если через telnet посылать эти же сообщения то все корректно доставляются хоть 2 это 20, ни одного не теряет.
Кто сталкивался с данным траблом?

gloomyBrain 05.05.2011 21:59

Сокет в ас3 читает данные до первого встреченного нуль-байта. Поищите по форуму, уже были подобные темы про склеивание сообщений

cremnet 05.05.2011 22:01

дык сообщение содержит \0 на конце
Проблема в том что если сообщения идут один за одним, он пропускает их. Примерная потеря 10% из отправленых сообщений

Добавлено через 9 минут
тему похожую нашел, но решения не понял http://www.flasher.ru/forum/showthre...ghlight=socket
кто поможет расжевать?

Добавлено через 25 минут
помогло добавлять два нуля вконце каждого сообщения
нифига... жаже два раза по \x00 не помогает... и \x00\x00\x00 не хочет... какимто волшебным образом 2ва раза получилось получить успешный результат... вобщем трабл пока не решен

Добавлено через 1 час 11 минут
похоже я сам себе отвечу:
Быть может весь трабл хранится сдесь http://www.javaspecialist.ru/2011/04/socket-api.html

etc 06.05.2011 00:05

Цитата:

Сообщение от gloomyBrain (Сообщение 994209)
Сокет в ас3 читает данные до первого встреченного нуль-байта.

Это если используется XMLSocket.

cremnet 06.05.2011 00:28

я запутался в конец,... исходя из выше упомянутой статьи нужно ставить схему запрос->ответ. Как бы все становитсяпонятно, если мы отправили сообщение, и оно не было получено, то отправляем его вновь. Получается мы на запрос делаем ответ на ответ - ответ? мой мозг рекурсирует, я завис

Добавлено через 7 минут
вот ситуация, конкретно которая у меня:
1 К серверу подключается 2ва сокета (гладко).
2 Один сокет создает виртуальную группу (ок).
3 Второй сокет запрашивает подключение к виртуальной группе, в ответ на это ему приходит 2ва сообщения
- в группе новый сокет (приходит на все сокеты в группе) (приходит без проблем
- подключение к виртуальной группе установлено (!сообщение сервером высылается, но до сокета не доходит)

wvxvw 06.05.2011 00:47

Есть предположение, что вы считываете содержание в строку, и потом эту строку в trace() - так да, вы увидете только до первого нуль-байта. Но вообще, ну, по крайней мере в теории TCP не должен терять пакеты. Разве что провод сетевой перерезать :)

cremnet 06.05.2011 01:13

Цитата:

Сообщение от wvxvw (Сообщение 994252)
Есть предположение, что вы считываете содержание в строку, и потом эту строку в trace() - так да, вы увидете только до первого нуль-байта. Но вообще, ну, по крайней мере в теории TCP не должен терять пакеты. Разве что провод сетевой перерезать :)

ХЗ...
Код AS3:

                private function connectToServer(host:String,port:int):void{
                        Security.loadPolicyFile("xmlsocket://"+host+':'+port);
                        if (host && port) 
                        {
                                socket.connect(host, port);
                        } else return;
 
                        socket.addEventListener(Event.CLOSE, closeHandler);       
                        socket.addEventListener(Event.CONNECT, connectHandler);
                        socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
                        socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
                        socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
 
                }
                private function readResponse() : void {
 
                        var str:String = socket.readUTFBytes(socket.bytesAvailable);
                        trace(str);
                }
                private function sendRequest(str:String) : void {
                        writeln(str);
                        socket.flush();
                }
 
                private function writeln(str:String) : void {
                        try
                        {
                                socket.writeUTFBytes(str);
                        }
                        catch (e:IOError)
                        {
                                trace(e);
                        }
                }
                private function socketDataHandler(event : ProgressEvent) : void {
                        trace('ProgressEvent');
                        readResponse();
                }

Добавлено через 13 минут
доработал функцию readResponse чтобы проверить есть ли что нибудь после нуля
Код AS3:

                private function readResponse() : void {
 
                        var str:String = socket.readUTFBytes(socket.bytesAvailable);
                        trace(str,'-str');
                        var str2:String = socket.readUTFBytes(socket.bytesAvailable);
                        trace(str2,'-str2');
                }

Там пусто. И ваще не логично чтобы два сообщения шли в одном.
Данный сокет сервер устрое так что собщения отправляются из разных мест (классы)
Класс состояния группы слушает события в группе и на них реагирует (сокет вошел, сокет ушел.... и тд)
Класс контроллер проверяет можно ли пользователю в группу и логинет его туда(если можно) и выдает соответствующий ответ успешно или нет

Добавлено через 19 минут
Цитата:

Сообщение от etc (Сообщение 994246)
Это если используется XMLSocket.

flash.net.Socket

wvxvw 06.05.2011 01:44

> Там пусто. И ваще не логично чтобы два сообщения шли в одном.
О каких сообщениях речь? Вы не получаете сообщения, вы получаете пакеты (сколько-то одновременно). От того сколько вы записали в сокет за один раз вдруг пропускная способность не поменяется... Более того, принимающая сторона понятия не имеет где / когда у вас наступает конец "сообщения".
Считайте сначала в ByteArray, потом byteArray.toString().split("\x00") - и посмотрите, что пришло. Так удобнее. try-catch при записи в сокет - не знаю зачем он вам... лучше сами проверьте подключен или нет. А еще лучше - ничего не ловите, пусть лучше словит тот, кто ломился писать в закрытый сокет.

cremnet 06.05.2011 01:53

Цитата:

Сообщение от wvxvw (Сообщение 994264)
> Там пусто. И ваще не логично чтобы два сообщения шли в одном.
О каких сообщениях речь? Вы не получаете сообщения, вы получаете пакеты (сколько-то одновременно). От того сколько вы записали в сокет за один раз вдруг пропускная способность не поменяется... Более того, принимающая сторона понятия не имеет где / когда у вас наступает конец "сообщения".
Считайте сначала в ByteArray, потом byteArray.toString().split("\x00") - и посмотрите, что пришло. Так удобнее. try-catch при записи в сокет - не знаю зачем он вам... лучше сами проверьте подключен или нет. А еще лучше - ничего не ловите, пусть лучше словит тот, кто ломился писать в закрытый сокет.

я как собака, все понимаю но сказать не могу... я на флеше без пяти минут месяц пишу

wvxvw 06.05.2011 03:14

http://en.wikipedia.org/wiki/Maximum_segment_size
Ну вот а теперь представьте худший вариант, вы посылаете пакеты минимально приемлимой длины: 536 байтов. Для одного текстового сообщения этого скорее всего будет более чем достаточно. (В Виндовс обычно сокет отркытый на локальной машине и общающийся с локальным же сокетом будет посылать ~4 килобайта за раз, но, как видно из статьи нету никаких специальных ограничений). Но когда вы посылаете несколько сообщений, то они будут соответственно складываться в поток, естесственным образом так, как вы их и записали, и получать их сокет будет по пакетам, а не по сообщениям. Он может получать их "по сообщениям" если интервал между записью сообщений достаточно большой, чтобы получить первое сообщение до того, как отправится второе - но этого бессмысленно добиваться даже в локальной сети / на одной машине = медленно. Лучше записывать либо сумму байтов сообщения, либо байт / последовательность байтов которые сигналят получение полного сообщения, либо данные должны иметь формат, который сам однозначно определяет длину сообщения.


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

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