我尝试创建自己的websocket服务器。它在Safari和Opera上运行良好,但不能在Firefox 8和Chrome 15上运行。
对于设置连接,我使用如下代码
private static void Response(Socket client, string secKey)
{
string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(secKey + guid));
string acceptKey = Convert.ToBase64String(hash);
client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine));
client.Send(Encoding.UTF8.GetBytes("Upgrade: WebSocket" + Environment.NewLine));
client.Send(Encoding.UTF8.GetBytes("Connection: Upgrade" + Environment.NewLine));
client.Send(Encoding.UTF8.GetBytes("Sec-WebSocket-Accept: " + acceptKey + Environment.NewLine));
}
发送消息:
var mess = Encoding.UTF8.GetBytes(DateTime.Now.ToString());
item.Send(new byte[] { 129 });
item.Send(new byte[] { (byte)mess.Length });
item.Send(mess);
谁能帮我指出我的错误吗? 该代码仅适用于Firefox 8和Chrome 15及更高版本。所以我假设你的早期浏览器的工作代码与你发布的不同,因为它们有不同的连线格式。
你的代码有几个问题:
- 如果浏览器发送了一个协议头,你需要选择并发送回一个协议。
- 您需要在每个标题(CR+LF, 'rn', 0x0D0A)之后发送回车+换行。
- 在最后的标题之后,你需要发送一个额外的回车+换行(即:'rnrn')表示握手完成。
你的发送算法也过于简单(虽然应该适用于你的例子)。如果消息长度超过126字节,则必须将该长度编码为帧头的多个字节。
还请注意,对于接收帧,您将需要取消有效负载的掩码。负载的前四个字节是掩码值。您需要将这些值与以下有效负载值进行异或。如规范中所述:
j = i MOD 4
transformed-octet-i = original-octet-i XOR masking-key-octet-j