所以我在c#中开发一个Web Socket服务器有一个正确的Web Socket升级,而且我在接收帧的时候,我似乎错误地解码了这些帧,
处理从框架读取的代码
bool started = false;
// to write something back.
while (bClientConnected)
{
try
{
msg = this.decryptFrame(client.Client);
Console.WriteLine("Client Frame Decrypt: " + msg);
//sWriter.WriteLine("pong!");
//sWriter.Flush();
}
catch (Exception)
{
Console.WriteLine("Connection from " + ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString() + " was terminated unkown reason.");
bClientConnected = false;
client.Close();
continue;
}
started = true;
}
解析和调试帧的代码:
public string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
private string decryptFrame(Socket sock)
{
// busy wait untill something is sent
while (sock.Available == 0) { }
var header = new byte[6];
sock.Receive(header);
var length = header[1] & 127;
Console.WriteLine("Recived header >> " + this.ByteArrayToString(header));
var body = new byte[length];
sock.Receive(body);
Console.WriteLine("Recived body >> " + this.ByteArrayToString(body));
for (var i = 0; i < length; i++)
{
body[i] ^= header[2 + (i & 3)];
}
Console.WriteLine("decoded body >> " + this.ByteArrayToString(body));
string resp = Encoding.UTF8.GetString(body, 0, length);
Console.WriteLine("Parsed body >> " + resp);
return resp;
}
问题是chrome框架在框架视图中立即显示(Opcode -1)
,发送到我服务器的唯一框架被调试为
Recived header >> 88909495d0d4
Recived body >> 977f85bafffbbfa3fab5bfa4f7fab4b1
decoded body >> 03ea556e6b6e6f776e206f70636f6465
Parsed body >> ?Unknown opcode
Client Frame Decrypt: ?Unknown opcode
答案 0 :(得分:2)
这篇文章是一个好的开始:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
具体来说,我认为你处理得不好the frame length。
- 读取位9-15(包括)并将其解释为无符号 整数。如果它是125或更小,那么这是长度;你完成了。 如果是126,请转到步骤2.如果是127,请转到步骤3.
读取下16位并将其解释为无符号整数。你已经完成了。
- 醇>
读取下一个64位并将其解释为无符号整数 (最重要的位必须是0)。你已经完成了。
我这里没有VS,但在这里你举了一个奇怪的例子:
var buffer = new byte[8192];
// put a frame in the buffer
// I am assuming that the frame is complete, starting at byte 0.
// Usually you will have to deal with incomplete frames
FillBuffer(buffer);
// length is in the second byte
int length = buffer[1];
// in the second byte, the first bit enables or disables MASK
// this bit would add a value of +128 (2^7) if enabled
length = (value >= 128 ? value - 128:value);
if(length == 126) // medium size frame
length = BitConverter.ToUint16(frame, 2);
else if(length == 127) // big ass frame
length = BitConverter.ToUint64(frame, 2);
else if(length > 127)
throw new InvalidOperationException($"Invalid frame length {length}");
我在C#中开发一个WebSocket组件,如果您有疑问,可能会发现代码很有趣:https://github.com/vtortola/WebSocketListener
答案 1 :(得分:0)
这是因为目前Chrome和Chrome中部署的实施方案似乎存在问题。 Firefox由于某种原因\ r \ n没有结束Sec-WebSocket-Accept
标题中的行,因此需要一个空格,因此在浏览器中关于标题上的\r\n
的实现有问题
"HTTP/1.1 101 Switching Protocols\r\n"
+ "Connection: Upgrade\r\n"
+ "Upgrade: websocket\r\n"
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(
new Regex("Sec-WebSocket-Key: (.*)").Match(headerBlock).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
)
)
) + " \r\n\r\n";