Firefox 8和Chrome 15中的websockets

时间:2011-12-10 19:38:26

标签: c# websocket

我尝试创建自己的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);

有人可以帮助我并指出我的错误吗?

1 个答案:

答案 0 :(得分:1)

该代码仅适用于Firefox 8和Chrome 15及更高版本。因此,我假设您使用早期浏览器的工作代码与您发布的不同,因为它们具有不同的线格式。

您的代码存在以下问题:

  • 如果浏览器发送协议标题(它可能会发送),您需要选择并发回协议。
  • 您需要在每个标题后发送一个回车+换行符(CR + LF,'\ r \ n',0x0D0A)。
  • 在最终标题之后,您需要发送额外的回车+换行符(即'\ r \ n \ r \ n')以指示握手完成。

您的发送算法也过于简单(尽管应该适用于您的示例)。如果消息的长度超过126个字节,则必须将长度编码为帧头的多个字节。

另请注意,对于接收帧,您需要取消屏蔽有效负载。有效载荷的前四个字节是掩蔽值。您需要将这些值与以下有效负载值进行异或。正如described in the spec

j                   = i MOD 4
transformed-octet-i = original-octet-i XOR masking-key-octet-j