TCP Socket 帧“排队”在 Windows 上。如何强制每条消息在其自己的框架中?
我使用 Actionscript 3 TCP 套接字与 Javascript Websockets 连接。发送数据主要是从websocket到AS socket。
在 Mac OS X 上,没问题。然而在 Windows 上,连续的 TCP 消息似乎在某个地方排队。这会导致 ProgressEvent.SOCKET_DATA
事件以相当长的时间间隔触发,从而产生明显的滞后。
我使用 Wireshark 来监控 OS X 和 Windows 上的 TCP 数据包。我看到的区别是,在 OS X 上,每条消息都包含在它自己的数据包中,而在 Windows 上,连续的消息被“串联”成一个数据包。
这只是套接字的实现方式,还是有什么方法可以改进?
编辑1: 我在actionscript.org上找到了这篇文章概述了相同的问题
编辑2:我找到了解决该问题的方法。我用虚拟文本填充每条消息以增加框架大小。这会导致 TCP 堆栈在其自己的帧中发送每条消息,而不是对它们进行排队。这是可行的,尽管它真的非常难看……
这是 SOCKET_DATA
事件中的代码。
while(this.socket.bytesAvailable) {
var byte:uint = this.socket.readUnsignedByte();
if(byte == 0x00) {
trace("Start byte found. - " + new Date().time);
this.incomingMessageBytes = new ByteArray();
} else if (byte == 0xFF) {
trace("End byte found. Dispatching. - " + new Date().time);
this.incomingMessageBytes.position = 0;
var msg:String = incomingMessageBytes.readUTFBytes(incomingMessageBytes.bytesAvailable);
var decodedMessage:Object = JSON.decode(msg, false);
var message = new Message(decodedMessage.clientId, decodedMessage.command, decodedMessage.data);
this.dispatchEvent(new MessageReceivedEvent(MessageReceivedEvent.RECEIVED_MESSAGE, message));
} else {
//trace("Appending.");
this.incomingMessageBytes.writeByte(byte);
}
}
I use Actionscript 3 TCP sockets to connect with Javascript websockets. Sending data is primarily from the websocket to the AS socket.
On Mac OS X, no problem. On Windows however, successive TCP messages seem to queue up somewhere. This causes the ProgressEvent.SOCKET_DATA
event to fire with quite a large time interval, which creates noticeable lag.
I used Wireshark to monitor the TCP packets on both OS X and Windows. The difference I see is that on OS X each message comes in it's own packet, while on Windows successive messages are 'concatenated' into one packet.
Is this just the way the socket is implemented, or is there any way I can improve on this?
EDIT 1: I found this post on actionscript.org which outlines the same problem
EDIT 2: I found a way to go around the problem. I pad every message with dummy text to increase the frame size. This causes the TCP stack to send every message in it's own frame instead if queuing them. This works, even though it's really, really ugly...
This is the code in the SOCKET_DATA
event.
while(this.socket.bytesAvailable) {
var byte:uint = this.socket.readUnsignedByte();
if(byte == 0x00) {
trace("Start byte found. - " + new Date().time);
this.incomingMessageBytes = new ByteArray();
} else if (byte == 0xFF) {
trace("End byte found. Dispatching. - " + new Date().time);
this.incomingMessageBytes.position = 0;
var msg:String = incomingMessageBytes.readUTFBytes(incomingMessageBytes.bytesAvailable);
var decodedMessage:Object = JSON.decode(msg, false);
var message = new Message(decodedMessage.clientId, decodedMessage.command, decodedMessage.data);
this.dispatchEvent(new MessageReceivedEvent(MessageReceivedEvent.RECEIVED_MESSAGE, message));
} else {
//trace("Appending.");
this.incomingMessageBytes.writeByte(byte);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
听起来您可能会看到内格尔算法的效果。我不知道是否有办法在 ActionScript 下禁用 Nagle 算法(也称为设置 TCP_NODELAY 标志),但如果有,您可以尝试这样做。
It sounds like you might be seeing the effects of Nagle's algorithm. I don't know if there is a way to disable Nagle's algorithm (aka setting the TCP_NODELAY flag) under ActionScript, but if there is, you might try doing that.