我在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
:这包含消息的完整字节,我尝试将这些字节转换回图像。
但是它给出了它无效的参数数据的例外。