TCP Socket 帧“排队”在 Windows 上。如何强制每条消息在其自己的框架中?

发布于 2024-12-04 17:16:04 字数 1551 浏览 1 评论 0原文

我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我一直都在从未离去 2024-12-11 17:16:04

听起来您可能会看到内格尔算法的效果。我不知道是否有办法在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文