Javascript 通过Websocket接收二进制数据
我有一个C#中的web套接字应用程序,另一个是连接到web套接字的小html页面,然后在web套接字C#应用程序上发送它正确接收的消息 当我尝试发送图像数据时,问题出现了。首先,我将图像数据转换为base 64字符串,然后通过JavaScript将字符串转换为Uint8Array,并将该数组缓冲区发送到我的C#Websocket应用程序 数据长度相同,但当我试图将从web浏览器接收到的字节数组转换为我的C#应用程序时,它无法正确转换为Base 64字符串并在我的C#应用程序上获得正确的图像 请看代码 Java脚本端:Javascript 通过Websocket接收二进制数据,javascript,c#,html,websocket,tcplistener,Javascript,C#,Html,Websocket,Tcplistener,我有一个C#中的web套接字应用程序,另一个是连接到web套接字的小html页面,然后在web套接字C#应用程序上发送它正确接收的消息 当我尝试发送图像数据时,问题出现了。首先,我将图像数据转换为base 64字符串,然后通过JavaScript将字符串转换为Uint8Array,并将该数组缓冲区发送到我的C#Websocket应用程序 数据长度相同,但当我试图将从web浏览器接收到的字节数组转换为我的C#应用程序时,它无法正确转换为Base 64字符串并在我的C#应用程序上获得正确的图像 请看
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);
函数StringToBinary(字符串){
变量字符,代码,i,isUCS2,len,_i;
len=字符串长度;
字符=[];
isUCS2=false;
对于(i=_i=0;0 len;i=0 255){
isUCS2=true;
chars=null;
打破
}否则{
字符推送(代码);
}
}
如果(isUCS2==true){
返回unescape(encodeURIComponent(string));
}否则{
返回String.fromCharCode.apply(null,Array.prototype.slice.apply(chars));
}
}
函数StringToUint8Array(字符串){
变量二进制,宾伦,缓冲区,字符,i,_i;
二进制=字符串二进制(字符串);
binLen=binary.length;
缓冲区=新阵列缓冲区(binLen);
chars=新的Uint8Array(缓冲区);
对于(i=_i=0;0 binLen;i=0>7);
//有效负载长度存储在第二个字节的前七位
var payloadLength=(ulong)(缓冲区[1]&0x7F);
//来自RFC-6455-第5.2节
//“如果为126,则以下解释为16位无符号整数的2个字节为有效负载长度
//(以网络字节顺序表示)
if(有效负载长度==TwoByteLengthCode)
{
数组。反向(缓冲区,payloadStartIndex,2);
payloadLength=BitConverter.ToUInt16(缓冲区,payloadStartIndex);
payloadStartIndex+=2;
}
//来自RFC-6455-第5.2节
//如果为127,则以下8个字节解释为64位无符号整数(最高有效位必须为0)
//是有效负载长度(以网络字节顺序表示)”
else if(有效负载长度==八字节长度代码)
{
数组。反向(缓冲区,payloadStartIndex,8);
payloadLength=BitConverter.ToUInt64(缓冲区,payloadStartIndex);
payloadStartIndex+=8;
}
frame.PayloadLength=有效负载长度;
//来自RFC-6455-第5.2节
//“从客户端发送到服务器的所有帧都被一个
//帧中包含的32位值。此字段为
//如果掩码位设置为1,则出现;如果掩码位为1,则不存在
//设置为0。“
如果(被问到)
{
frame.MaskingKey=BitConverter.ToInt32(缓冲区,payloadStartIndex);
payloadStartIndex+=4;
}
//缓冲区=新字节[(int)frame.PayloadLength+payloadStartIndex];
var content=新字节[frame.PayloadLength];
//复制(缓冲区,payloadStartIndex,内容,0,(int)frame.PayloadLength);
如果(被问到)
取消掩码(内容、帧、掩码键);
frame.UnmaskedPayload=内容;
返回框;
}
私有静态无效解除掩码(字节[]有效负载,int maskingKey)
{
int currentMaskIndex=0;
byte[]byteKeys=BitConverter.GetBytes(maskingKey);
对于(int index=0;index
frame.UnmaskedPayload
:这包含消息的完整字节,我尝试将这些字节转换回图像
但它给出了一个例外,即它的参数数据无效。如果您将用于转换实际图像中字节的代码放入实际图像中,则可能是值得的。当我尝试转换为图像时,它会给我一个错误,即参数无效。我的be我的数据没有正确地转换成图像字节。这是你应该把代码的方式。我看不到转换为base64stringNo body的理由,因为没有任何主体响应我的线程。我迫切需要请任何人在这个问题上添加一些灯光/
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;
}
}