예제 #1
0
        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;
        }
예제 #2
0
 public void Send(string data)
 {
     var frame = new Frame(Frame.Opcodes.Text, Encoding.UTF8.GetBytes(data), true);
     Send(frame);
 }
예제 #3
0
        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);
        }
예제 #4
0
 public void Send(byte[] data)
 {
     var frame = new Frame(Frame.Opcodes.Binary, data, true);
     Send(frame);
 }