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

XBEEN 01.02.2011 14:06

Socket, алгоритм склеивания данных
 
Доброго времени суток!

Подскажите, пожалуйста, какой-нибудь грамотный алгоритм склеивания данных в сокете и как проверить при считывании данных из сокета их целостность (кусок это или полный пакет)

avilov 01.02.2011 14:17

берешь байтовый массив рубаешь его на пакеты по сколько тебе нужно , в каждый пакет заносишь номер пакета и количество байт которые будут в этом пакете - и начинаешь отгружать.

XBEEN 01.02.2011 14:20

А есть хоть какой-нить наглядный примерчик? Так проще разобраться.

CrazyFlasher 01.02.2011 14:35

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

gloomyBrain 01.02.2011 14:38

Цитата:

в каждый пакет заносишь номер пакета и количество байт которые будут в этом пакете
А номер-то зачем? =)

По поводу примерчика - неужели так сложно сделать writeShort(длина массива данных) перед записью самих данных?

avilov 01.02.2011 14:49

[quote=gloomyBrain;969510]А номер-то зачем? =)

вдруг какого то пакета нет после передачи , можно повторно запросить и указать какой пакет нужен

XBEEN 01.02.2011 14:53

Спасибо, принцип понял. А пример нужен для большей ясности...

avilov 01.02.2011 14:55

Цитата:

Сообщение от XBEEN (Сообщение 969517)
Спасибо, принцип понял. А пример нужен для большей ясности...

Это значит вы нечего не поняли !

Добавлено через 4 минуты
не изобретай велосипед , TCP/IP гарантирует передачу и целостность данных , он сам продублирует не хватающие пакеты

gloomyBrain 01.02.2011 15:32

Цитата:

вдруг какого то пакета нет после передачи
Цитата:

TCP/IP гарантирует передачу и целостность данных
По-моему, Вы сами себе противоречите... =)

Однако, я могу захотеть отправить больше, чем влезает в пакет TCP, тогда мне становится нужно дописывать длину пакета в его начале

avilov 01.02.2011 16:10

Цитата:

Сообщение от gloomyBrain (Сообщение 969532)
Однако, я могу захотеть отправить больше, чем влезает в пакет TCP, тогда мне становится нужно дописывать длину пакета в его начале

А сколько влазит в один пакет ?

gloomyBrain 01.02.2011 16:13

А это зависит от MTU
от 576 до 1500 байт

avilov 01.02.2011 16:26

Код AS3:

Socket.writeBytes();

Засовываете любой обьем данных , он сам раскидает его на пакеты , и он будет считаться как один пакет , правда передаваться будет кусками это уже ТСР его сам разделит на нужные куски , на сервере данные будут доступны когда все пакеты будут переданы.

gloomyBrain 01.02.2011 16:51

В данном аспекте все зависит от сервера. По идее - да. На практике - не всегда

avilov 01.02.2011 17:00

главное что б когда в Socket.writeBytes(); передаются байты , не было там нулевого байта , тогда они придут все за раз придут

ChuwY 01.02.2011 17:17

Не все. Сказали же выше.

А вообще посмотрите вот эту тему

etc 02.02.2011 00:53

Вписываем длину пакета. Если пришло меньше, ждем ещё кусок. Всё.

Psycho Tiger 02.02.2011 01:07

Цитата:

Сообщение от XBEEN (Сообщение 969517)
Спасибо, принцип понял. А пример нужен для большей ясности...

Отдуши.
Код AS3:

package artshlagin.network 
{
        import flash.events.DataEvent;
        import flash.events.Event;
        import flash.events.IOErrorEvent;
        import flash.events.ProgressEvent;
        import flash.events.SampleDataEvent;
        import flash.events.SecurityErrorEvent;
        import flash.net.Socket;
        import flash.utils.ByteArray;
 
        /**
        * ...
        * @author Artem Shlagin
        */

 
        [Event(name = "sampleData", type = "flash.events.SampleDataEvent")]
 
        public class BinarySocket extends Socket
        {
                /**
                * Два байта выделять под заголовок (true) или один (false)
                */

                public static var HEADER_BYTES_DOUBLE:Boolean = true;
 
                /**
                * Два байта выделять под заголовок (true) или один (false)
                */

                public static var MESSAGE_LENGTH_DOUBLE:Boolean = true;
 
 
                private var _responseByteArray:ByteArray;
                private var _messageLength:uint;
 
                /**
                * Класс для обмена бинарными данными с сокет-сервером
                * @param        host
                * @param        port
                */

                public function BinarySocket(host:String = null, port:int = 0)
                {
                        super(host, port);
                        super.addEventListener(Event.CONNECT, onConnect);
 
                        _messageLength = 0;
                        _responseByteArray = new ByteArray();
                }
 
                public function send(packet:uint, message:ByteArray = null):void {
                        HEADER_BYTES_DOUBLE ? super.writeShort(packet) : super.writeByte(packet);
                        if (message) {
                                var l:uint = message.length;
                                MESSAGE_LENGTH_DOUBLE ? super.writeShort(l) : super.writeByte(l);
                                super.writeBytes(message);
                        }
                        else MESSAGE_LENGTH_DOUBLE ? super.writeShort(0) : super.writeByte(0);
                        super.flush();
                }
                private function onConnect(event:Event):void
                {
                        super.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
                }
 
                protected function onSocketData(event:ProgressEvent):void
                {
                        var ba:uint;
                        var headerBytes:uint = HEADER_BYTES_DOUBLE ? 2 : 1;
                        var messageBytes:uint = MESSAGE_LENGTH_DOUBLE ? 2 : 1;
                        do {
 
                                ba = super.bytesAvailable;
                                if (_messageLength > 0) { //reading message
                                        if (ba >= _messageLength) {
                                                super.readBytes(_responseByteArray, headerBytes, _messageLength);
                                                flushToClient();
                                        }
                                        else return; //reading only a full message, or wait
                                }
                                else{
                                        if (_responseByteArray.length >= headerBytes) { //header passed
                                                if (ba >= messageBytes) { //reading message length if can
                                                        _messageLength = MESSAGE_LENGTH_DOUBLE ? super.readUnsignedShort() : super.readUnsignedByte();
                                                        if (!_messageLength) flushToClient(); //if no message
                                                }
                                                else return; // or waiting to load full length
                                        }
 
                                        else { // if header is not passed - reading
                                                if (ba >= headerBytes) { //reading header if can
                                                        super.readBytes(_responseByteArray, 0, headerBytes);
                                                }
                                                else return; //or waiting to load full header
                                        }
                                }
 
                        }
 
                        while (super.bytesAvailable); //NOT ba, мы считывали байты после калькуляции ba
 
                }
 
                /**
                * Отправляет данные клиенту
                */

                protected function flushToClient():void {
                        _messageLength = 0;
                        var event:SampleDataEvent = new SampleDataEvent(SampleDataEvent.SAMPLE_DATA);
                        _responseByteArray.position = 0;
                        event.data = _responseByteArray;
                        _responseByteArray = new ByteArray();
                        super.dispatchEvent(event);
 
                }
 
        }
 
}



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

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