简体   繁体   中英

Websocket closes with large messages

I'm writing ac# web socket implementation and Whenever I send messages greater than 65535 bytes; the client (Javascript) fails to load the message and closes the connection. (It was previously saying invalid frame, now it says nothing)

I am encoding the messages like so

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;
    }

Messages under 65535 bytes send fine. Any help is appreciated.

To clarify the message im trying to send is 120283 bytes; error code is 1006

For messages up to 125 bytes, the code is correct. For messages > 125 but <= 65536 bytes, i need to write 3 bytes - the first byte is 126; the following 2 bytes give the message length. For messages > 65536 bytes, i need to write 9 bytes - the first byte is 127; the following 8 bytes give the message length.

As you can see I do all of this in the above code, but the message fails to send .

It looks like there's a bug in this:

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);

This is because you are trying to bitshift a 32bit number over 8 bytes, even though Int32 is only 4 bytes long. Net result, you end up storing the same 32bit number twice over the 8 bytes. You could convert length to a ulong and use that value instead, and your code should work. Otherwise...

I prefer to use someone else's code for something as boring as bitshifting.

This bitshifting code (and its bugs) has propagated far and wide (you're not the first person to see this issue).

If you grab Jon Skeet's MiscUtil from nuget , you'll get a better result with the following code (with the added bonus that it's a much easier read):

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

The bug is in sending a long variable, but length is Int32. There are a few ways to solve it, for example:

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);

I tested this code and works fine!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM