Javascript Websocket会以大消息关闭
我正在编写一个c#web套接字实现,每当我发送大于65535字节的消息时;客户端(Javascript)无法加载消息并关闭连接。(它以前说的是无效帧,现在什么也没说) 我是这样编码信息的Javascript Websocket会以大消息关闭,javascript,c#,websocket,Javascript,C#,Websocket,我正在编写一个c#web套接字实现,每当我发送大于65535字节的消息时;客户端(Javascript)无法加载消息并关闭连接。(它以前说的是无效帧,现在什么也没说) 我是这样编码信息的 public static Byte[] EncodeMessageToSend(String message) { Byte[] response; Byte[] bytesRaw = Encoding.UTF8.GetBytes(message); B
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;
}
公共静态字节[]EncodeMessageToSend(字符串消息)
{
字节[]响应;
Byte[]bytesRaw=Encoding.UTF8.GetBytes(消息);
字节[]帧=新字节[10];
Int32 indexStartRawData=-1;
Int32长度=字节原始长度;
帧[0]=(字节)129;
如果(长度=126&&length>8)&255);
帧[3]=(字节)(长度为255);
indexStartRawData=4;
}
其他的
{
帧[1]=(字节)127;
帧[2]=(字节)((长度>>56)和255);
帧[3]=(字节)((长度>>48)和255);
帧[4]=(字节)((长度>>40)和255);
帧[5]=(字节)((长度>>32)和255);
帧[6]=(字节)((长度>>24)和255);
帧[7]=(字节)((长度>>16)和255);
帧[8]=(字节)((长度>>8)和255);
帧[9]=(字节)(长度为255);
indexStartRawData=10;
}
响应=新字节[indexStartRawData+长度];
Int32 i,reponseIdx=0;
//将帧字节添加到响应中
对于(i=0;i
65535字节以下的消息发送正常。感谢您的帮助
澄清我试图发送的消息是120283字节;错误代码是1006
对于最多125字节的消息,代码是正确的。
对于大于125但65536字节的消息,我需要写入9个字节-第一个字节是127;以下8个字节给出了消息长度
正如您所看到的,我在上面的代码中完成了所有这些操作,但消息无法发送。这里面似乎有一个bug:
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);
这是因为您正在尝试将32位数字位移到8个字节以上,即使Int32
只有4个字节长。最终,您将在8个字节上存储相同的32位数字两次。您可以将length
转换为ulong
并使用该值,您的代码应该可以工作。否则
我更喜欢用别人的代码来做像比特转换这样无聊的事情
这种位移位代码(及其bug)已经传播得很广(你不是第一个看到这个问题的人)
如果您从中获取Jon Skeet的MiscUtil,您将使用以下代码获得更好的结果(另外,它更易于阅读):
看起来这里面有个bug:
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);
这是因为您正在尝试将32位数字位移到8个字节以上,即使Int32
只有4个字节长。最终,您将在8个字节上存储相同的32位数字两次。您可以将length
转换为ulong
并使用该值,您的代码应该可以工作。否则
我更喜欢用别人的代码来做像比特转换这样无聊的事情
这种位移位代码(及其bug)已经传播得很广(你不是第一个看到这个问题的人)
如果您从中获取Jon Skeet的MiscUtil,您将使用以下代码获得更好的结果(另外,它更易于阅读):
错误在于发送长变量,但长度为Int32。 有几种方法可以解决此问题,例如:
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);
我测试了这段代码,效果很好 错误在于发送长变量,但长度为Int32。 有几种方法可以解决此问题,例如:
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);
我测试了这段代码,效果很好 看起来您将受益于Jon Skeet在()中的EndianBitConverter,它将使您的代码更易于阅读。看起来您将受益于Jon Skeet在()中的EndianBitConverter,它将使您的代码更易于阅读。非常好,已修复。我自己也不是原始代码的粉丝,所以这是一个受欢迎的变化。很好,修正了。我自己并不喜欢原始代码,所以这是一个受欢迎的变化。