C# 和 JS 中的 WebSocketServers - 作为回报的胡言乱语

WebSocketServers in C# and JS - Gibberish in return

本文关键字:回报 胡言乱语 JS 中的 WebSocketServers      更新时间:2023-09-26

我用C#制作了一个Websocket服务器,并与JS一起制作了一个HTML UI。

我可以让服务器进行通信并正确握手,但是发送的信息绝对是胡言乱语,看起来像这样:

???=u??X?G?

我尝试过对其进行编码,但结果并没有太大的不同。

我的JS看起来像这样:

    // the user clicked the big red button
    $('#bigredbutton_send').click(function () {
        ws_send($('#console_input').val());
    });
    $('#console_input').keyup(function (e) {
        if(e.keyCode == 13) // enter is pressed
            ws_send($('#console_input').val());
    });

.CSS:

    <input type="image" src="button.png"  name="bigredbutton_send" id="bigredbutton_send" value="VALUE" /> 
    <input type="text" name="console_input" id="console_input" value="Hello123" />

接收信息的 C# 模块如下所示:

        private void Read(IAsyncResult ar)
    {
        int sizeOfReceivedData = ConnectionSocket.EndReceive(ar);
        if (sizeOfReceivedData > 0)
        {
            int start = 0, end = dataBuffer.Length - 1;
            // if we are not already reading something, look for the start byte as specified in the protocol
            if (!readingData)
            {
                for (start = 0; start < dataBuffer.Length - 1; start++)
                {
                    if (dataBuffer[start] == (byte)WrapperBytes.Start)
                    {
                        readingData = true; // we found the begining and can now start reading
                        start++; // we dont need the start byte. Incrementing the start counter will walk us past it
                        break;
                    }
                }
            } // no else here, the value of readingData might have changed
            // if a begining was found in the buffer, or if we are continuing from another buffer
            if (readingData)
            {
                bool endIsInThisBuffer = false;
                // look for the end byte in the received data
                for (end = start; end < sizeOfReceivedData; end++)
                {
                    byte currentByte = dataBuffer[end];
                    if (dataBuffer[end] == (byte)WrapperBytes.End)
                    {
                        endIsInThisBuffer = true; // we found the ending byte
                        break;
                    }
                }
                // the end is in this buffer, which means that we are done reading
                if (endIsInThisBuffer == true)
                {
                    // we are no longer reading data
                    readingData = false;
                    // put the data into the string builder
                    dataString.Append(Encoding.UTF8.GetString(dataBuffer, start, end - start));
                    // trigger the event
                    int size = Encoding.UTF8.GetBytes(dataString.ToString().ToCharArray()).Length;
                    recievedData = dataString.ToString();
                    OnDataReceived(new DataReceivedEventArgs(size, dataString.ToString()));
                    dataString = null;
                    dataString = new StringBuilder();

                }
                else // if the end is not in this buffer then put everyting from start to the end of the buffer into the datastring and keep on reading
                {
                    dataString.Append(Encoding.UTF8.GetString(dataBuffer, start, end - start));
                }
            }
            // continue listening for more data
            Listen();
        }
        else // the socket is closed
        {
            if (Disconnected != null)
                Disconnected(this, EventArgs.Empty);
        }

        // Testing to see if readable
        ReadRecievedData(Convert.ToString(dataString));
    }
它们

都返回一些东西,但是,它们总是返回这个原始的、乱码状的数据,看起来像这样:

???=u??X?G?

我知道它缺乏编码,并且我已经尝试对其进行了几次编码 - 但这些信息看起来更奇怪,实际上永远不会返回我想要的任何内容。任何帮助将不胜感激。

更新

在调用新连接时调用 dataBuffer。

        public WebSocketConnection(Socket socket, int bufferSize)
    {
        ConnectionSocket = socket;
        dataBuffer = new byte[bufferSize];
        dataString = new StringBuilder();
        GUID = System.Guid.NewGuid();
        Listen();
    }

Listen() 创建这个:

        private void Listen()
    {
        ConnectionSocket.BeginReceive(dataBuffer, 0, dataBuffer.Length, 0, Read, null);
    }

解决!

昨天又看了一遍,我解决了问题。我没有正确解析位 - 所以我创建了这个:

    byte b = dataBuffer[1];
    int dataLength = 0;
    int totalLength = 0;
    int keyIndex = 0;
    int length = dataBuffer.Length;
    if (b - 128 <= 125)
    {
        dataLength = b - 128;
        keyIndex = 2;
        totalLength = dataLength + 6;
    }
    if (b - 128 == 126)
    {
        dataLength = BitConverter.ToInt16(new byte[] { dataBuffer[3], dataBuffer[2] }, 0);
        keyIndex = 4;
        totalLength = dataLength + 8;
    }
    if (b - 128 == 127)
    {
        dataLength = (int)BitConverter.ToInt64(new byte[] { dataBuffer[9], dataBuffer[8], dataBuffer[7], dataBuffer[6], dataBuffer[5], dataBuffer[4], 
            dataBuffer[3], dataBuffer[2] }, 0);
        keyIndex = 10;
        totalLength = dataLength + 14;
    }
    if (totalLength > length)
        throw new Exception("The buffer length is small than the data length");
    byte[] key = new byte[] { dataBuffer[keyIndex], dataBuffer[keyIndex + 1], dataBuffer[keyIndex + 2], dataBuffer[keyIndex + 3] };
    int dataIndex = keyIndex + 4;
    int count = 0;
    for (int i = dataIndex; i < totalLength; i++)
    {
        dataBuffer[i] = (byte)(dataBuffer[i] ^ key[count % 4]);
        count++;
    }
    ReadRecievedData(Encoding.ASCII.GetString(dataBuffer, dataIndex, dataLength));

它基于此处的解决方案构建如何在 WebSockets hybi 08+ 中(解)建数据帧?

WebSocket 数据是成帧的,因此您必须逐帧读取并从中提取数据。

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

用 C# 编写 WebSocket 服务器

编写 WebSocket 服务器

请尝试这个

private void Read(IAsyncResult ar)
{
    int sizeOfReceivedData = ConnectionSocket.EndReceive(ar);
    if (sizeOfReceivedData > 0)
    {
        int start = 0, end = sizeOfReceivedData - 1;
        var bufferList = dataBuffer.ToList();
        bool endIsInThisBuffer = dataBuffer.Contains(255); // 255 = end
        if (endIsInThisBuffer)
        {
            end = bufferList.IndexOf(255);
            end--; // we dont want to include this byte
        }
        bool startIsInThisBuffer = dataBuffer.Contains(0); // 0 = start
        if (startIsInThisBuffer)
        {
            var zeroPos = bufferList.IndexOf(0);
            if (zeroPos < end) // we might be looking at one of the bytes in the end of the array that hasn't been set
            {
                start = zeroPos;
                start++; // we dont want to include this byte
            }
        }
        dataString.Append(Encoding.UTF8.GetString(dataBuffer, start, (end - start) + 1));
        if (endIsInThisBuffer)
        {
            var data = dataString.ToString();
            OnDataReceived(new DataReceivedEventArgs(data.Length, data));
            // Testing to see if readable
            ReadRecievedData(data);
            dataString = new StringBuilder();
        }
        Listen();
    }
    else // the socket is closed
    {
        if (Disconnected != null)
            Disconnected(this, EventArgs.Empty);
    }
}

解决了!

昨天又看了一遍,我解决了问题。我没有正确解析位 - 所以我创建了这个:

byte b = dataBuffer[1];
int dataLength = 0;
int totalLength = 0;
int keyIndex = 0;
int length = dataBuffer.Length;
if (b - 128 <= 125)
{
    dataLength = b - 128;
    keyIndex = 2;
    totalLength = dataLength + 6;
}
if (b - 128 == 126)
{
    dataLength = BitConverter.ToInt16(new byte[] { dataBuffer[3], dataBuffer[2] }, 0);
    keyIndex = 4;
    totalLength = dataLength + 8;
}
if (b - 128 == 127)
{
    dataLength = (int)BitConverter.ToInt64(new byte[] { dataBuffer[9], dataBuffer[8], dataBuffer[7], dataBuffer[6], dataBuffer[5], dataBuffer[4], 
        dataBuffer[3], dataBuffer[2] }, 0);
    keyIndex = 10;
    totalLength = dataLength + 14;
}
if (totalLength > length)
    throw new Exception("The buffer length is small than the data length");
byte[] key = new byte[] { dataBuffer[keyIndex], dataBuffer[keyIndex + 1], dataBuffer[keyIndex + 2], dataBuffer[keyIndex + 3] };
int dataIndex = keyIndex + 4;
int count = 0;
for (int i = dataIndex; i < totalLength; i++)
{
    dataBuffer[i] = (byte)(dataBuffer[i] ^ key[count % 4]);
    count++;
}
ReadRecievedData(Encoding.ASCII.GetString(dataBuffer, dataIndex, dataLength));

它基于此处的解决方案构建如何在 WebSockets hybi 08+ 中(解)建数据帧?