二进制数据通过Websocket接收

时间:2014-12-09 11:19:04

标签: javascript c# html5 websocket tcplistener

我在C#中有Web套接字应用程序,其他我有一个小的html页面连接到我的Web套接字,然后在我的Web套接字C#应用程序上正确发送它收到的消息。

当我尝试发送图像数据时出现问题。首先,我将图像数据转换为base 64字符串,然后通过JavaScript将字符串转换为Uint8Array,并将该数组缓冲区发送到我的C#Websocket应用程序。

数据长度相同,但是当我尝试将从Web浏览器收到的字节数组转换为我的C#应用​​程序时,它无法正确转换为Base 64字符串并在我的C#应用​​程序上获得正确的图像。

请参阅代码

Java Script方面:

function StringToBinary(string) {
            var chars, code, i, isUCS2, len, _i;

            len = string.length;
            chars = [];
            isUCS2 = false;
            for (i = _i = 0; 0 <= len ? _i < len : _i > len; i = 0 <= len ? ++_i : --_i) {
                code = String.prototype.charCodeAt.call(string, i);
                if (code > 255) {
                    isUCS2 = true;
                    chars = null;
                    break;
                } else {
                    chars.push(code);
                }
            }
            if (isUCS2 === true) {
                return unescape(encodeURIComponent(string));
            } else {
                return String.fromCharCode.apply(null, Array.prototype.slice.apply(chars));
            }
        }
        function StringToUint8Array(string) {
            var binary, binLen, buffer, chars, i, _i;
            binary = StringToBinary(string);
            binLen = binary.length;
            buffer = new ArrayBuffer(binLen);
            chars = new Uint8Array(buffer);
            for (i = _i = 0; 0 <= binLen ? _i < binLen : _i > binLen; i = 0 <= binLen ? ++_i : --_i) {
                chars[i] = String.prototype.charCodeAt.call(binary, i);
            }
            return chars;
        }

 function StringToArrayBuffer(string) {
            return StringToUint8Array(string).buffer;
        }
//Canvas to get the Base64string
var data = ctx.toDataURL('image/png')
  var StringbinaryBuffer = StringToArrayBuffer(data);

webSocket.send(StringbinaryBuffer);

C#代码:

public static Frame FromBuffer(byte[] buffer)
        {
            var frame = new Frame();

            // If no extended payload length and no mask are used, the payload starts at the 3rd byte
            int payloadStartIndex = 2;

            var firstNibble = (byte)(buffer[0] & 0xF0);
            var secondNibble = (byte)(buffer[0] & 0x0F);

            // When the first bit of the first byte is set,
            // It means that the current frame is the final frame of a message
            if (firstNibble == Fin)
                frame.IsFin = true;

            //  The opcode consists of the last four bits in the first byte
            //frame.Opcode = (Opcodes)secondNibble;
            frame.Opcode = (Opcodes)secondNibble; ;

            // The last bit of the second byte is the masking bit
            bool isMasked = Convert.ToBoolean((buffer[1] & 0x80) >> 7);

            // Payload length is stored in the first seven bits of the second byte
            var payloadLength = (ulong)(buffer[1] & 0x7F);

            // From RFC-6455 - Section 5.2
            // "If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length
            // (expressed in network byte order)"
            if (payloadLength == TwoBytesLengthCode)
            {
                Array.Reverse(buffer, payloadStartIndex, 2);
                payloadLength = BitConverter.ToUInt16(buffer, payloadStartIndex);
                payloadStartIndex += 2;
            }

            // From RFC-6455 - Section 5.2
            // "If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) 
            // are the payload length (expressed in network byte order)"
            else if (payloadLength == EightBytesLengthCode)
            {
                Array.Reverse(buffer, payloadStartIndex, 8);
                payloadLength = BitConverter.ToUInt64(buffer, payloadStartIndex);
                payloadStartIndex += 8;
            }

            frame.PayloadLength = payloadLength;

            // From RFC-6455 - Section 5.2
            // "All frames sent from the client to the server are masked by a
            // 32-bit value that is contained within the frame.  This field is
            // present if the mask bit is set to 1 and is absent if the mask bit
            // is set to 0."
            if (isMasked)
            {
                frame.MaskingKey = BitConverter.ToInt32(buffer, payloadStartIndex);
                payloadStartIndex += 4;
            }
            //buffer = new byte[(int)frame.PayloadLength + payloadStartIndex];
            var content = new byte[frame.PayloadLength];
            // Array.Copy(buffer, payloadStartIndex, content, 0, (int)frame.PayloadLength);

            if (isMasked)
                UnMask(content, frame.MaskingKey);

            frame.UnmaskedPayload = content;

            return frame;
        }
 private static void UnMask (byte[] payload, int maskingKey)
        {
            int currentMaskIndex = 0;

            byte[] byteKeys = BitConverter.GetBytes(maskingKey);
            for (int index = 0; index < payload.Length; ++index)
            {
                payload[index] = (byte)(payload[index] ^ byteKeys[currentMaskIndex]);
                currentMaskIndex = (++currentMaskIndex)%4;
            }
        }

frame.UnmaskedPayload:这包含消息的完整字节,我尝试将这些字节转换回图像。

但是它给出了它无效的参数数据的例外。

0 个答案:

没有答案