AS3 / AIR readObject () из сокета - как проверить, все ли данные получены? - PullRequest
1 голос
/ 08 сентября 2011

Если вы пишете простой объект в сокет:

var o:Object = new Object();
o.type = e.type;
o.params = e.params;
_socket.writeObject(o);
_socket.flush();

Тогда на клиенте вы просто используете:

private function onData(e:ProgressEvent):void
{
    var o:Object = _clientSocket.readObject();
}

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

Ответы [ 4 ]

2 голосов
/ 09 сентября 2011

Есть 2 подхода:

Если вы уверены, что ваш объект поместится в один пакет, вы можете сделать что-то вроде:

var fromServer:ByteArray = new ByteArray;

while( socket.bytesAvailable )
    socket.readBytes( fromServer );

fromServer.position = 0;
var myObj:* = fromServer.readObject();

Если у вас есть возможность иметь несколькопакетные сообщения, тогда обычно используют для добавления в сообщение длину сообщения.Что-то вроде (псевдокод):

var fromServer:ByteArray    = new ByteArray();
var msgLen:int              = 0;

while ( socket.bytesAvailable > 0 )
{
    // if we don't have a message length, read it from the stream
    if ( msgLen == 0 )
        msgLen = socket.readInt();

    // if our message is too big for one push
    var toRead:int  = ( msgLen > socket.bytesAvailable ) ? socket.bytesAvailable : msgLen;
    msgLen          -= toRead; // msgLen will now be 0 if it's a full message

    // read the number of bytes that we want.
    // fromServer.length will be 0 if it's a new message, or if we're adding more
    // to a previous message, it'll be appended to the end
    socket.readBytes( fromServer, fromServer.length, toRead );

    // if we still have some message to come, just break
    if ( msgLen != 0 )
        break;

    // it's a full message, create your object, then clear fromServer
}

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

1 голос
/ 15 февраля 2012

Правило № 1 при работе с TCP: это протокол передачи потока октетов.Вы никогда не можете предположить, что сколько октетов (8-битных значений, обычно называемых байтами) вы получаете за один раз, всегда пишите код, который может обрабатывать любое количество, как слишком мало, так и слишком много.Нет гарантии, что запись не будет разбита на несколько операций чтения.Также нет гарантии, что одно чтение будет из одной записи.

0 голосов
/ 27 января 2012

Если вы хотите только отправить Объекты, самое простое решение - если вы отправляете int (размер) перед каждым объектом. Не важно отправить точный размер, вы можете отправить немного меньше. В моем случае я отправил растровые данные, а также ширину и высоту объекта. очевидно, размер растрового изображения настолько велик, и это нормально, если вы отправляете только это и игнорируете все остальное.

var toRead=0;
protected function onSocketData(event:ProgressEvent):void{
                if(toRead==0) {
                toRead=socket.readInt() 
            }
            if(socket.bytesAvailable>toRead){
                var recieved:Object=socket.readObject() 
                /*do stuff with recieved object*/
                toRead=0
            }
0 голосов
/ 08 сентября 2011

Способ, которым я справился, состоял в том, чтобы сделать обратный вызов, чтобы сервер сообщил клиенту, что нулевой бит был получен.
Нулевой бит добавляется в конец строки данных, которую вы отправляете на сервер.

String.fromCharCode(0)

Также в вашем случае вы делаете

_socket.writeObject(o);

Вы должны отправлять строку, а не объект.
Вот так.

_socket.writeUTFBytes( 'Hellow World" + String.fromCharCode(0) );

ПРИМЕЧАНИЕ *************
И одна вещь, которую большинство создателей сокетов первый раз смотрят на это Дело в том, что первый запрос от клиента к серверу через порт, к которому подключен сокет, является запросом crossdomainpolicy.xml

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...