/// <summary> /// 解析请求的数据 /// 返回请求数据包 /// </summary> /// <param name="streamReader">数据读取器</param> /// <param name="requiredMask">是否要求必须Mask</param> /// <exception cref="NotSupportedException"></exception> /// <returns></returns> public static FrameRequest Parse(IByteStream streamReader, bool requiredMask = true) { if (streamReader.Length < 2) { return(null); } ByteBits byte0 = streamReader.ReadByte(); bool fin = byte0[0]; ByteBits rsv = byte0.Take(1, 3); FrameCodes frameCode = (FrameCodes)(byte)byte0.Take(4, 4); ByteBits byte1 = streamReader.ReadByte(); bool 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(); } int contentSize = 0; int contentLength = byte1.Take(1, 7); if (contentLength == 127) { contentSize = 8; contentLength = (int)streamReader.ReadLong(); } else if (contentLength == 126) { contentSize = 2; contentLength = (ushort)streamReader.ReadShort(); } int maskSize = mask ? 4 : 0; int packetLength = 2 + maskSize + contentSize + contentLength; if (streamReader.Length < packetLength) { return(null); } byte[] maskingKey = mask ? streamReader.ReadBytes(4) : null; byte[] content = streamReader.ReadBytes(contentLength); if (mask && contentLength > 0) { for (int i = 0; i < contentLength; i++) { content[i] = (byte)(content[i] ^ maskingKey[i % 4]); } } return(new FrameRequest { Fin = fin, Rsv = rsv, Mask = mask, Frame = frameCode, ContentLength = contentLength, MaskingKey = maskingKey, Content = content }); }
/// <summary> /// 构建回复帧 /// </summary> /// <param name="frame">帧类型</param> /// <param name="content">内容</param> /// <param name="fin">是否结束帧</param> /// <exception cref="ArgumentNullException"></exception> public FrameResponse(FrameCodes frame, byte[] content, bool fin) { this.Frame = frame; this.Fin = fin; this.Content = content ?? new byte[0]; }
/// <summary> /// 回复对象 /// </summary> /// <param name="frame">帧类型</param> /// <param name="content">内容</param> /// <exception cref="ArgumentNullException"></exception> public FrameResponse(FrameCodes frame, byte[] content) { this.Frame = frame; this.Content = content ?? new byte[0]; }
/// <summary> /// 构建不分片的回复帧 /// </summary> /// <param name="frame">帧类型</param> /// <param name="content">内容</param> /// <exception cref="ArgumentNullException"></exception> public FrameResponse(FrameCodes frame, byte[] content) : this(frame, content, fin : true) { }