来自套接字的AS3 / AIR readObject() - 如何检查收到的所有数据?

时间:2011-09-08 08:29:05

标签: actionscript-3 sockets

如果您将一个简单的对象写入套接字:

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 个答案:

答案 0 :(得分: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 :(得分:1)

处理TCP时的规则#1:它是八位字节流传输协议。您可能永远不会假设您一次性获得多少八位字节(8位长值,通常称为字节),始终编写可以处理任何数量的代码,包括太少和太多。没有保证写入不会被分成多个读取。也没有保证一次读取将来自一次写入。

答案 2 :(得分:0)

我处理它的方法是回调服务器告诉客户端已收到空位 空位将附加到要发送到服务器的数据字符串的末尾。

String.fromCharCode(0)

同样在你的情况下你正在做

_socket.writeObject(o);

你应该发送一个字符串而不是一个对象 所以就这样。

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

* ** * ** * ** * ** *
大多数第一次插座创作者看到的一件事是 事实上,第一个请求从客户端到服务器上方 套接字连接的端口是请求 crossdomainpolicy.xml

答案 3 :(得分:0)

如果您只想发送对象,最简单的解决方案是在每个对象之前发送一个int(大小)。发送确切的大小并不重要,你可以发送少一点。在我的例子中,我发送了一个bitmapdata,以及对象的宽度和高度。很明显,bitmapdata的大小是如此之大,如果只发送它就可以了,忽略其余部分。

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
            }