public static Frame FromBuffer(byte[] buffer) { var frame = new Frame(); // If no extended payload length and no mask are used, the payload starts at the 3rd byte int payloadStartIndex = 2; var firstNibble = (byte)(buffer[0] & 0xF0); var secondNibble = (byte)(buffer[0] & 0x0F); // When the first bit of the first byte is set, // It means that the current frame is the final frame of a message if (firstNibble == Fin) frame.IsFin = true; // The opcode consists of the last four bits in the first byte frame.Opcode = (Opcodes)secondNibble; // The last bit of the second byte is the masking bit bool isMasked = Convert.ToBoolean((buffer[1] & 0x80) >> 7); // Payload length is stored in the first seven bits of the second byte var payloadLength = (ulong)(buffer[1] & 0x7F); // From RFC-6455 - Section 5.2 // "If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length // (expressed in network byte order)" if (payloadLength == TwoBytesLengthCode) { Array.Reverse(buffer, payloadStartIndex, 2); payloadLength = BitConverter.ToUInt16(buffer, payloadStartIndex); payloadStartIndex += 2; } // From RFC-6455 - Section 5.2 // "If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0) // are the payload length (expressed in network byte order)" else if (payloadLength == EightBytesLengthCode) { Array.Reverse(buffer, payloadStartIndex, 8); payloadLength = BitConverter.ToUInt64(buffer, payloadStartIndex); payloadStartIndex += 8; } frame.PayloadLength = payloadLength; // From RFC-6455 - Section 5.2 // "All frames sent from the client to the server are masked by a // 32-bit value that is contained within the frame. This field is // present if the mask bit is set to 1 and is absent if the mask bit // is set to 0." if (isMasked) { frame.MaskingKey = BitConverter.ToInt32(buffer, payloadStartIndex); payloadStartIndex += 4; } var content = new byte[frame.PayloadLength]; Array.Copy(buffer, payloadStartIndex, content, 0, (int)frame.PayloadLength); if (isMasked) UnMask(content, frame.MaskingKey); frame.UnmaskedPayload = content; return frame; }
public void Send(string data) { var frame = new Frame(Frame.Opcodes.Text, Encoding.UTF8.GetBytes(data), true); Send(frame); }
private void Send(Frame frame) { if (!m_isConnected) return; byte[] buffer = frame.ToBuffer(); var sendEventArgs = new SocketAsyncEventArgs(); sendEventArgs.SetBuffer(buffer, 0, buffer.Length); m_tcpClient.Client.SendAsync(sendEventArgs); }
public void Send(byte[] data) { var frame = new Frame(Frame.Opcodes.Binary, data, true); Send(frame); }