AS3服务器套接字、进度事件、读UTF字节
我遇到了一点问题。
我正在做一个多人游戏,使用Flash来做客户端,服务器端则用Python。我已经让socket连接工作了……算是吧,Python的部分也做了不少,但我碰到了一个奇怪的问题。
假设在登录时,我会发送一些数据给客户端,里面包含他们的一些信息。然后,我再发送一些数据来把他们分配到一个房间。
但是,这些数据在AS3中似乎没有被当作两件不同的事情来读取,反而在用readUTFBytes读取后,所有内容都变成了同一个字符串。
var str:String = event.currentTarget.readUTFBytes(event.currentTarget.bytesAvailable);
在Python中,我定义了一些方法来发送数据,这些方法通过transport.write(Twisted)发送数据,而我在ActionScript中通过一个进度socket数据事件来接收数据。你觉得这里可能出什么问题吗?这里有一段代码……
if ( ! event.currentTarget.bytesAvailable > 0) {
return;
}
var str:String = event.currentTarget.readUTFBytes(event.currentTarget.bytesAvailable);
var Char1:String = str.charAt(0);
var Char2:String = str.charAt(1);
str = str.replace(Char1, "");
str = str.replace(Char2, "");
// Various messages
if (Char1 == "\x03") {
if (Char2 == "\x03") {
trace("Got ping thread");
}
else {
trace("x03 but no secondary prefix handled");
}
return;
}
我知道代码写得很乱,但我只是想找出问题所在。
所有数据都有两个前缀,比如\x02和\x09,这样我就能知道该怎么处理,然后大部分数据在字符串中是通过\x01来分割以获取值。
问题的关键是,我应该得到\x08\x08的数据,但我却得到了\x08\x08的数据和\x05\x03的数据,这本来应该是两件不同的事情。
1 个回答
TCP连接是可靠的、有序的、以流为基础的传输方式。这里的“流”指的是一串字节,没有固定的消息边界。如果你想把这些字节分成不同的消息,那么字节本身需要告诉你怎么分(或者你需要一些外部规则,比如“每条消息是5个字节长”)。
这个规则适用于所有TCP连接,无论你用什么编程语言,或者使用什么特定的库(比如readUTFBytes
)。
有很多种协议可以帮助你框定你的消息。例如,你可以使用长度前缀。这样你的消息看起来会是这样的:
\x07 \x08 \x08 h e l l o \x05 \x05 \x03 m a n
\x07
表示第一条消息的长度是7个字节:\x08 \x08 h e l l o
。紧接着的字节\x05
表示第二条消息的长度:\x05 \x03 m a n
。
如果你的消息需要更长,可以使用多字节长度前缀,或者使用netstrings,这种方式用十进制表示长度,并用:
作为分隔符,支持任意大小的前缀。还有一些更复杂的协议,提供比单纯分隔字节更丰富的功能。例如,有一个叫AMP的协议,它提供了一种带参数和响应的远程过程调用(RPC)形式。