Websocket以大消息关闭

时间:2015-12-02 01:34:08

标签: javascript c# websocket

我正在编写一个c#web套接字实现,每当我发送大于65535字节的消息时;客户端(Javascript)无法加载消息并关闭连接。 (之前曾说过无效的框架,现在却什么都没说)

我正在编码这样的消息

public static Byte[] EncodeMessageToSend(String message)
    {
        Byte[] response;
        Byte[] bytesRaw = Encoding.UTF8.GetBytes(message);
        Byte[] frame = new Byte[10];

        Int32 indexStartRawData = -1;
        Int32 length = bytesRaw.Length;

        frame[0] = (Byte)129;
        if (length <= 125)
        {
            frame[1] = (Byte)length;
            indexStartRawData = 2;
        }
        else if (length >= 126 && length <= 65535)
        {
            frame[1] = (Byte)126;
            frame[2] = (Byte)((length >> 8) & 255);
            frame[3] = (Byte)(length & 255);
            indexStartRawData = 4;
        }
        else
        {
            frame[1] = (Byte)127;
            frame[2] = (Byte)((length >> 56) & 255);
            frame[3] = (Byte)((length >> 48) & 255);
            frame[4] = (Byte)((length >> 40) & 255);
            frame[5] = (Byte)((length >> 32) & 255);
            frame[6] = (Byte)((length >> 24) & 255);
            frame[7] = (Byte)((length >> 16) & 255);
            frame[8] = (Byte)((length >> 8) & 255);
            frame[9] = (Byte)(length & 255);

            indexStartRawData = 10;
        }

        response = new Byte[indexStartRawData + length];

        Int32 i, reponseIdx = 0;

        //Add the frame bytes to the reponse
        for (i = 0; i < indexStartRawData; i++)
        {
            response[reponseIdx] = frame[i];
            reponseIdx++;
        }

        //Add the data bytes to the response
        for (i = 0; i < length; i++)
        {
            response[reponseIdx] = bytesRaw[i];
            reponseIdx++;
        }

        return response;
    }

65535字节以下的消息发送正常。任何帮助表示赞赏。

澄清我试图发送的消息是120283字节;错误代码是1006

对于最多125字节的消息,代码是正确的。 对于消息&gt; 125但是&lt; = 65536字节,我需要写3个字节 - 第一个字节是126;以下2个字节给出了消息长度。 对于消息&gt; 65536字节,我需要写9个字节 - 第一个字节是127;以下8个字节给出了消息长度。

正如您所看到的,我在上面的代码中执行了所有操作,但邮件无法发送。

2 个答案:

答案 0 :(得分:3)

看起来这里有一个错误:

frame[1] = (Byte)127;

frame[2] = (Byte)((length >> 56) & 255);
frame[3] = (Byte)((length >> 48) & 255);
frame[4] = (Byte)((length >> 40) & 255);
frame[5] = (Byte)((length >> 32) & 255);
frame[6] = (Byte)((length >> 24) & 255);
frame[7] = (Byte)((length >> 16) & 255);
frame[8] = (Byte)((length >> 8) & 255);
frame[9] = (Byte)(length & 255);

这是因为你试图将8位字节的32位数字进行位移,即使Int32只有4个字节长。净结果,您最终在8个字节上存储两次相同的32位数。您可以将length转换为ulong并改用该值,并且您的代码应该有效。否则...

我更倾向于使用别人的代码来做一些无聊的事情。

这个位移代码(及其错误)已经广泛传播(你不是第一个看到这个问题的人)。

如果你从nuget抓住Jon Skeet的MiscUtil,你会得到一个更好的结果,使用下面的代码(附加的奖励是更容易阅读):

frame[1] = (byte)127;
EndianBitConverter.Big.CopyBytes((ulong)length, frame, 2);

答案 1 :(得分:0)

错误在于发送长变量,但长度为Int32。 有几种解决方法,例如:

frame[1] = (Byte)127;
frame[2] = 0;
frame[3] = 0;
frame[4] = 0;
frame[5] = 0;
frame[6] = (Byte)((length >> 24) & 255);
frame[7] = (Byte)((length >> 16) & 255);
frame[8] = (Byte)((length >> 8) & 255);
frame[9] = (Byte)(length & 255);

我测试了此代码,并且工作正常!