/// <summary> /// 设置握手结果 /// </summary> /// <param name="inputStream">输入流</param> /// <returns></returns> public bool TrySetResult(IStreamReader inputStream) { inputStream.Position = 0; var index = inputStream.IndexOf(DoubleCrlf); if (index < 0) { return(false); } var length = index + DoubleCrlf.Length; var header = inputStream.ReadString(Encoding.ASCII, length); inputStream.Clear(length); const string pattern = @"^HTTP/1.1 101 Switching Protocols\r\n((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+\r\n"; var match = Regex.Match(header, pattern, RegexOptions.IgnoreCase); if (match.Success == true) { var httpHeader = HttpHeader.Parse(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures); var secAccept = httpHeader["Sec-WebSocket-Accept"]; const string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; var bytes = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(this.secKey + guid)); var secValue = Convert.ToBase64String(bytes); if (secValue == secAccept) { return(this.TrySetResult(SocketError.Success)); } } return(this.TrySetResult(SocketError.SocketError)); }
/// <summary> /// 解析请求的数据 /// 返回请求数据包 /// </summary> /// <param name="stream">所有收到的数据</param> /// <param name="requiredMask">是否要求必须Mask</param> /// <exception cref="NotSupportedException"></exception> /// <returns></returns> public unsafe static FrameRequest Parse(IStreamReader stream, bool requiredMask = true) { if (stream.Length < 2) { return(null); } ByteBits byte0 = stream[0]; var fin = byte0[0]; var frameCode = (FrameCodes)(byte)byte0.Take(4, 4); if (fin == false || frameCode == FrameCodes.Continuation) { return(null); } var rsv = byte0.Take(1, 3); ByteBits byte1 = stream[1]; var mask = byte1[0]; if (requiredMask && mask == false) { throw new NotSupportedException("mask is required"); } if (Enum.IsDefined(typeof(FrameCodes), frameCode) == false || rsv != 0) { throw new NotSupportedException(); } var contentSize = 0; var contentLength = (int)byte1.Take(1, 7); stream.Position = 2; if (contentLength == 127) { contentSize = 8; contentLength = (int)stream.ReadUInt64(); } else if (contentLength == 126) { contentSize = 2; contentLength = (int)stream.ReadUInt16(); } var maskSize = mask ? 4 : 0; var packetLength = 2 + maskSize + contentSize + contentLength; if (stream.Length < packetLength) { return(null); } var maskingKey = mask ? stream.ReadArray(4) : null; var content = stream.ReadArray(contentLength); stream.Clear(packetLength); if (mask && contentLength > 0) { fixed(byte *pcontent = &content[0], pmask = &maskingKey[0]) { for (var i = 0; i < contentLength; i++) { *(pcontent + i) = (byte)(*(pcontent + i) ^ *(pmask + i % 4)); } } } return(new FrameRequest { Fin = fin, Rsv = rsv, Mask = mask, Frame = frameCode, ContentLength = contentLength, MaskingKey = maskingKey, Content = content }); }
/// <summary> /// 解析一个数据包 /// 不足一个封包时返回null /// </summary> /// <param name="stream">接收到的历史数据</param> /// <param name="packet">数据包</param> /// <returns></returns> public static bool Parse(IStreamReader stream, out FastPacket packet) { if (stream.Length < 1 || stream[0] != FastPacket.Mark) { packet = null; return(false); } if (stream.Length < 5) { packet = null; return(true); } stream.Position = 1; const int packetMinSize = 16; var totalBytes = stream.ReadInt32(); if (totalBytes < packetMinSize) { packet = null; return(false); } // 数据包未接收完整 if (stream.Length < totalBytes) { packet = null; return(true); } // api名称数据长度 var apiNameLength = stream.ReadByte(); if (totalBytes < apiNameLength + packetMinSize) { packet = null; return(false); } // api名称数据 var apiNameBytes = stream.ReadArray(apiNameLength); // 标识符 var id = stream.ReadInt64(); // 是否为客户端封包 var isFromClient = stream.ReadBoolean(); // 是否异常 var isException = stream.ReadBoolean(); // 实体数据 var body = stream.ReadArray(totalBytes - stream.Position); // 清空本条数据 stream.Clear(totalBytes); var apiName = Encoding.UTF8.GetString(apiNameBytes); packet = new FastPacket(apiName, id, isFromClient) { TotalBytes = totalBytes, ApiNameLength = apiNameLength, IsException = isException, Body = body }; return(true); }