示例#1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WebSocketFrame"/> class.
 /// </summary>
 /// <param name="isEntirePayload">if set to <c>true</c> [is entire payload].</param>
 /// <param name="isValid">if set to <c>true</c> [is valid].</param>
 /// <param name="opCode">The op code.</param>
 /// <param name="decodedPayload">The decoded payload.</param>
 public WebSocketFrame(bool isEntirePayload, bool isValid, WebSocketOpCode opCode, byte[] decodedPayload)
 {
     IsEntirePayload = isEntirePayload;
     IsValid         = isValid;
     OpCode          = opCode;
     DecodedPayload  = decodedPayload;
 }
        public void Write(WebSocketOpCode opCode, byte[] payload, bool isLastFrame)
        {
            // best to write everything to a memory stream before we push it onto the wire
            // not really necessary but I like it this way
            using (MemoryStream memoryStream = new MemoryStream())
            {
                byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00;
                byte byte1           = (byte)(finBitSetAsByte | (byte)opCode);
                memoryStream.WriteByte(byte1);

                // NB, dont set the mask flag. No need to mask data from server to client
                // depending on the size of the length we want to write it as a byte, ushort or ulong
                if (payload.Length < 126)
                {
                    byte byte2 = (byte)payload.Length;
                    memoryStream.WriteByte(byte2);
                }
                else if (payload.Length <= ushort.MaxValue)
                {
                    byte byte2 = 126;
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream, false);
                }
                else
                {
                    byte byte2 = 127;
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream, false);
                }

                memoryStream.Write(payload, 0, payload.Length);
                byte[] buffer = memoryStream.ToArray();
                _stream.Write(buffer, 0, buffer.Length);
            }
        }
 public WebSocketFrame(bool isFinBitSet, WebSocketOpCode webSocketOpCode, int count, ArraySegment <byte> maskKey)
 {
     IsFinBitSet = isFinBitSet;
     OpCode      = webSocketOpCode;
     Count       = count;
     MaskKey     = maskKey;
 }
        /// <summary>
        /// Send data to the web socket
        /// </summary>
        /// <param name="buffer">the buffer containing data to send</param>
        /// <param name="messageType">The message type. Can be Text or Binary</param>
        /// <param name="endOfMessage">True if this message is a standalone message (this is the norm)
        /// If it is a multi-part message then false (and true for the last message)</param>
        /// <param name="cancellationToken">the cancellation token</param>
        public override async Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
        {
            using (MemoryStream stream = _recycledStreamFactory())
            {
                WebSocketOpCode opCode = GetOppCode(messageType);

                if (_usePerMessageDeflate)
                {
                    using (MemoryStream temp = new MemoryStream())
                    {
                        DeflateStream deflateStream = new DeflateStream(temp, CompressionMode.Compress);
                        deflateStream.Write(buffer.Array, buffer.Offset, buffer.Count);
                        deflateStream.Flush();
                        var compressedBuffer = new ArraySegment <byte>(temp.ToArray());
                        WebSocketFrameWriter.Write(opCode, compressedBuffer, stream, endOfMessage, _isClient);
                        Events.Log.SendingFrame(_guid, opCode, endOfMessage, compressedBuffer.Count, true);
                    }
                }
                else
                {
                    WebSocketFrameWriter.Write(opCode, buffer, stream, endOfMessage, _isClient);
                    Events.Log.SendingFrame(_guid, opCode, endOfMessage, buffer.Count, false);
                }

                await WriteStreamToNetwork(stream, cancellationToken);

                _isContinuationFrame = !endOfMessage;
            }
        }
示例#5
0
 public void SendingFrame(Guid guid, WebSocketOpCode webSocketOpCode, bool isFinBitSet, int numBytes, bool isPayloadCompressed)
 {
     if (this.IsEnabled(EventLevel.Verbose, EventKeywords.None))
     {
         WriteEvent(28, guid, webSocketOpCode, isFinBitSet, numBytes, isPayloadCompressed);
     }
 }
 public WebSocketFrame(bool isFinBitSet, WebSocketOpCode webSocketOpCode, byte[] decodedPayload, bool isValid)
 {
     IsFinBitSet = isFinBitSet;
     OpCode = webSocketOpCode;
     DecodedPayload = decodedPayload;
     IsValid = isValid;
 }
        /// <summary>
        /// Extracts close status and close description information from the web socket frame
        /// </summary>
        /// <param name="isFinBitSet"></param>
        /// <param name="opCode"></param>
        /// <param name="count"></param>
        /// <param name="buffer"></param>
        /// <returns></returns>
        static WebSocketFrame DecodeCloseFrame(bool isFinBitSet, WebSocketOpCode opCode, int count, ArraySegment <byte> buffer)
        {
            WebSocketCloseStatus closeStatus;
            string closeStatusDescription;

            if (count >= 2)
            {
                Array.Reverse(buffer.Array, buffer.Offset, 2);                 // network byte order
                var closeStatusCode = (int)BitConverter.ToUInt16(buffer.Array, buffer.Offset);
                closeStatus = Enum.IsDefined(typeof(WebSocketCloseStatus), closeStatusCode)
                                        ? (WebSocketCloseStatus)closeStatusCode
                                        : WebSocketCloseStatus.Empty;

                int offset    = buffer.Offset + 2;
                int descCount = count - 2;

                closeStatusDescription = descCount > 0
                                        ? Encoding.UTF8.GetString(buffer.Array, offset, descCount)
                                        : null;
            }
            else
            {
                closeStatus            = WebSocketCloseStatus.Empty;
                closeStatusDescription = null;
            }

            return(new WebSocketFrame(isFinBitSet, opCode, count, closeStatus, closeStatusDescription));
        }
示例#8
0
 public WebSocketFrame(bool isFinBitSet, WebSocketOpCode webSocketOpCode, byte[] decodedPayload, bool isValid)
 {
     IsFinBitSet    = isFinBitSet;
     OpCode         = webSocketOpCode;
     DecodedPayload = decodedPayload;
     IsValid        = isValid;
 }
        /// <summary>
        /// Send data to the web socket
        /// </summary>
        /// <param name="buffer">the buffer containing data to send</param>
        /// <param name="messageType">The message type. Can be Text or Binary</param>
        /// <param name="endOfMessage">True if this message is a standalone message (this is the norm)
        /// If it is a multi-part message then false (and true for the last message)</param>
        /// <param name="cancellationToken">the cancellation token</param>
        public override async Task SendAsync(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
        {
            using (MemoryStream stream = _recycledStreamFactory())
            {
                WebSocketOpCode opCode = GetOppCode(messageType);

                if (_usePerMessageDeflate)
                {
                    // NOTE: Compression is currently work in progress and should NOT be used in this library.
                    // The code below is very inefficient for small messages. Ideally we would like to have some sort of moving window
                    // of data to get the best compression. And we don't want to create new buffers which is bad for GC.
                    using (MemoryStream temp = new MemoryStream())
                    {
                        DeflateStream deflateStream = new DeflateStream(temp, CompressionMode.Compress);
                        deflateStream.Write(buffer.Array, buffer.Offset, buffer.Count);
                        deflateStream.Flush();
                        ArraySegment <byte> compressedBuffer = new ArraySegment <byte>(temp.ToArray());
                        WebSocketFrameWriter.Write(opCode, compressedBuffer, stream, endOfMessage, _isClient);
                        Events.Log.SendingFrame(_guid, opCode, endOfMessage, compressedBuffer.Count, true);
                    }
                }
                else
                {
                    WebSocketFrameWriter.Write(opCode, buffer, stream, endOfMessage, _isClient);
                    Events.Log.SendingFrame(_guid, opCode, endOfMessage, buffer.Count, false);
                }

                await WriteStreamToNetwork(stream, cancellationToken);

                // TODO: is this correct??
                _isContinuationFrame = !endOfMessage;
            }
        }
示例#10
0
 public void ReceivedFrame(Guid guid, WebSocketOpCode webSocketOpCode, bool isFinBitSet, int numBytes)
 {
     if (IsEnabled(EventLevel.Verbose, EventKeywords.None))
     {
         WriteEvent(29, guid, webSocketOpCode, isFinBitSet, numBytes);
     }
 }
示例#11
0
        public byte[] GetFrameBytesFromData(WebSocketOpCode opCode, byte[] payload, bool isLastFrame)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00;
                byte byte1           = (byte)(finBitSetAsByte | (byte)opCode);
                memoryStream.WriteByte(byte1);

                // NB, dont set the mask flag. No need to mask data from server to client
                // depending on the size of the length we want to write it as a byte, ushort or ulong
                if (payload.Length < 126)
                {
                    byte byte2 = (byte)payload.Length;
                    memoryStream.WriteByte(byte2);
                }
                else if (payload.Length <= ushort.MaxValue)
                {
                    byte byte2 = 126;
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream, false);
                }
                else
                {
                    byte byte2 = 127;
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream, false);
                }

                memoryStream.Write(payload, 0, payload.Length);
                byte[] buffer = memoryStream.ToArray();
                return(buffer);
            }
        }
示例#12
0
        /// Send data to the web socket
        public void Send(ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage)
        {
            using (MemoryStream stream = _recycledStreamFactory())
            {
                WebSocketOpCode opCode = GetOppCode(messageType);

                if (_usePerMessageDeflate)
                {
                    // NOTE: Compression is currently work in progress and should NOT be used in this library.
                    // The code below is very inefficient for small messages. Ideally we would like to have some sort of moving window
                    // of data to get the best compression. And we don't want to create new buffers which is bad for GC.
                    using (MemoryStream temp = new MemoryStream())
                    {
                        DeflateStream deflateStream = new DeflateStream(temp, CompressionMode.Compress);
                        deflateStream.Write(buffer.Array, buffer.Offset, buffer.Count);
                        deflateStream.Flush();
                        var compressedBuffer = new ArraySegment <byte>(temp.ToArray());
                        WebSocketFrameWriter.Write(opCode, compressedBuffer, stream, endOfMessage, _isClient);
                        _logger(LogLevel.Debug, $"websocket.SendingFrame: {opCode}, {endOfMessage}, {compressedBuffer.Count}, compressed");
                    }
                }
                else
                {
                    WebSocketFrameWriter.Write(opCode, buffer, stream, endOfMessage, _isClient);
                    _logger(LogLevel.Debug, $"websocket.SendingFrame: {opCode}, {endOfMessage}, {buffer.Count}, uncompressed");
                }

                WriteStreamToNetwork(stream);
                _isContinuationFrame = !endOfMessage; // TODO: is this correct??
            }
        }
示例#13
0
 public void Write(WebSocketOpCode opCode, byte[] payload, bool isLastFrame)
 {
     using (var memoryStream = new MemoryStream()) {
         var finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00;
         var byte1           = (byte)(finBitSetAsByte | (byte)opCode);
         memoryStream.WriteByte(byte1);
         if (payload.Length < 126)
         {
             var byte2 = (byte)payload.Length;
             memoryStream.WriteByte(byte2);
         }
         else if (payload.Length <= ushort.MaxValue)
         {
             byte byte2 = 126;
             memoryStream.WriteByte(byte2);
             BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream);
         }
         else
         {
             byte byte2 = 127;
             memoryStream.WriteByte(byte2);
             BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream);
         }
         memoryStream.Write(payload, 0, payload.Length);
         var buffer = memoryStream.ToArray();
         _stream.Write(buffer, 0, buffer.Length);
     }
 }
        public void Write(WebSocketOpCode opCode, byte[] payload, bool isLastFrame)
        {
            // best to write everything to a memory stream before we push it onto the wire
            // not really necessary but I like it this way
            using (MemoryStream memoryStream = new MemoryStream())
            {
                byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00;
                byte byte1 = (byte)(finBitSetAsByte | (byte)opCode);
                memoryStream.WriteByte(byte1);

                // NB, dont set the mask flag. No need to mask data from server to client
                // depending on the size of the length we want to write it as a byte, ushort or ulong
                if (payload.Length < 126)
                {
                    byte byte2 = (byte)payload.Length;
                    memoryStream.WriteByte(byte2);
                }
                else if (payload.Length <= ushort.MaxValue)
                {
                    byte byte2 = 126;
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream, false);
                }
                else
                {
                    byte byte2 = 127;
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream, false);
                }

                memoryStream.Write(payload, 0, payload.Length);
                byte[] buffer = memoryStream.ToArray();
                _stream.Write(buffer, 0, buffer.Length);
            }            
        }
示例#15
0
 public WebSocketFrame()
 {
     Payload  = null;
     OpCode   = WebSocketOpCode.Continue;
     IsFinal  = false;
     IsMasked = false;
 }
示例#16
0
        /// <summary>
        /// Reads the specified stream.
        /// </summary>
        /// <param name="connection">The connection.</param>
        /// <returns></returns>
        public IWebSocketFrame Read(TcpClient connection)
        {
            const byte FIN_BIT_FLAG = 0x80;
            const byte OP_CODE_FLAG = 0x0F;
            const byte MASK_FLAG    = 0x80;
            const int  KEY_LENGTH   = 4;

            if (!connection.Connected)
            {
                return(null);
            }

            //Process the first byte of the packet
            byte firstByte;

            try
            {
                firstByte = (byte)Stream.ReadByte();
            }
            catch (IOException ex)
            {
                _logger.Error(ex);
                return(null);
            }

            bool isFinBitSet = (firstByte & FIN_BIT_FLAG) == FIN_BIT_FLAG;

            //Gets the op code which tells us what kind of payload we're looking at (binary, message, etc)
            WebSocketOpCode opCode = (WebSocketOpCode)(firstByte & OP_CODE_FLAG);

            //Process the second byte of the packet
            byte secondByte = (byte)Stream.ReadByte();

            //Get the mask bit and toss an exception if it's false. Per the RFC this should never be false.
            bool isMaskBitSet = (secondByte & MASK_FLAG) == MASK_FLAG;

            if (!isMaskBitSet)
            {
                return(null);
            }

            //Grab the payload length
            uint payloadLength = ReadPayloadLength(secondByte, Stream);

            //Grab the crypto key from the stream
            byte[] maskKey = StreamHelper.ReadExactly(KEY_LENGTH, Stream);

            //Grab the encrypted payload
            byte[] encodedPayload = StreamHelper.ReadExactly((int)payloadLength, Stream);

            //Decrypt the payload
            byte[] decodedPayload = new byte[payloadLength];
            for (int i = 0; i < encodedPayload.Length; i++)
            {
                decodedPayload[i] = (Byte)(encodedPayload[i] ^ maskKey[i % KEY_LENGTH]);
            }

            return(new WebSocketFrame(isFinBitSet, true, opCode, decodedPayload));
        }
 protected override void Send(WebSocketOpCode opCode, byte[] toSend, bool isLastFrame)
 {
     byte[] buffer = _frameBuilder.GetFrameBytesFromData(opCode, toSend, isLastFrame);
     if (_socketHandler != null)
     {
         _socketHandler.Send(buffer);
     }
 }
示例#18
0
 public WebSocketFrame(bool isFinBitSet, WebSocketOpCode webSocketOpCode, int count)
 {
     IsFinBitSet            = isFinBitSet;
     OpCode                 = webSocketOpCode;
     Count                  = count;
     CloseStatus            = WebSocketCloseStatus.None;
     CloseStatusDescription = null;
 }
 public static bool IsValidCode(WebSocketOpCode opCode)
 {
     return(opCode == WebSocketOpCode.ContinuationFrame ||
            opCode == WebSocketOpCode.TextFrame ||
            opCode == WebSocketOpCode.BinaryFrame ||
            opCode == WebSocketOpCode.ConnectionClose ||
            opCode == WebSocketOpCode.Ping ||
            opCode == WebSocketOpCode.Pong);
 }
示例#20
0
 public void SendFrame(string Data, WebSocketOpCode OpCode, bool LastFrame)
 {
     if (ConnectedSocket.Connected)
     {
         WebSocketFrame Frame       = new WebSocketFrame(Data, OpCode);
         byte[]         FrameBuffer = Frame.GetRawBuffer(LastFrame);
         ConnectedSocket.BeginSend(FrameBuffer, 0, FrameBuffer.Length, SocketFlags.None, SendMessageCallback, null);
     }
 }
示例#21
0
        public WebSocketFrame Read(Stream stream, Socket socket)
        {
            byte byte1;

            try
            {
                byte1 = (byte)stream.ReadByte();
            }
            catch (IOException)
            {
                if (socket.Connected)
                {
                    throw;
                }
                else
                {
                    return(null);
                }
            }

            // process first byte
            byte            finBitFlag  = 0x80;
            byte            opCodeFlag  = 0x0F;
            bool            isFinBitSet = (byte1 & finBitFlag) == finBitFlag;
            WebSocketOpCode opCode      = (WebSocketOpCode)(byte1 & opCodeFlag);

            // read and process second byte
            byte byte2        = (byte)stream.ReadByte();
            byte maskFlag     = 0x80;
            bool isMaskBitSet = (byte2 & maskFlag) == maskFlag;
            uint len          = ReadLength(byte2, stream);

            byte[] decodedPayload;

            // use the masking key to decode the data if needed
            if (isMaskBitSet)
            {
                const int maskKeyLen     = 4;
                byte[]    maskKey        = BinaryReaderWriter.ReadExactly(maskKeyLen, stream);
                byte[]    encodedPayload = BinaryReaderWriter.ReadExactly((int)len, stream);
                decodedPayload = new byte[len];

                // apply the mask key
                for (int i = 0; i < encodedPayload.Length; i++)
                {
                    decodedPayload[i] = (Byte)(encodedPayload[i] ^ maskKey[i % maskKeyLen]);
                }
            }
            else
            {
                decodedPayload = BinaryReaderWriter.ReadExactly((int)len, stream);
            }

            WebSocketFrame frame = new WebSocketFrame(isFinBitSet, opCode, decodedPayload, true);

            return(frame);
        }
示例#22
0
        /// <summary>
        /// Read a WebSocket frame from the stream
        /// </summary>
        /// <param name="fromStream">The stream to read from</param>
        /// <param name="intoBuffer">The buffer to read into</param>
        /// <param name="cancellationToken">the cancellation token</param>
        /// <returns>A websocket frame</returns>
        public static async Task <WebSocketFrame> ReadAsync(Stream fromStream, ArraySegment <byte> intoBuffer, CancellationToken cancellationToken)
        {
            // allocate a small buffer to read small chunks of data from the stream
            var smallBuffer = new ArraySegment <byte>(new byte[8]);

            await BinaryReaderWriter.ReadExactly(2, fromStream, smallBuffer, cancellationToken);

            byte byte1 = smallBuffer.Array[0];
            byte byte2 = smallBuffer.Array[1];

            // process first byte
            byte            finBitFlag  = 0x80;
            byte            opCodeFlag  = 0x0F;
            bool            isFinBitSet = (byte1 & finBitFlag) == finBitFlag;
            WebSocketOpCode opCode      = (WebSocketOpCode)(byte1 & opCodeFlag);

            // read and process second byte
            byte maskFlag     = 0x80;
            bool isMaskBitSet = (byte2 & maskFlag) == maskFlag;
            uint len          = await ReadLength(byte2, smallBuffer, fromStream, cancellationToken);

            int count = (int)len;

            try
            {
                // use the masking key to decode the data if needed
                if (isMaskBitSet)
                {
                    ArraySegment <byte> maskKey = new ArraySegment <byte>(smallBuffer.Array, 0, WebSocketFrameCommon.MaskKeyLength);
                    await BinaryReaderWriter.ReadExactly(maskKey.Count, fromStream, maskKey, cancellationToken);

                    await BinaryReaderWriter.ReadExactly(count, fromStream, intoBuffer, cancellationToken);

                    ArraySegment <byte> payloadToMask = new ArraySegment <byte>(intoBuffer.Array, intoBuffer.Offset, count);
                    WebSocketFrameCommon.ToggleMask(maskKey, payloadToMask);
                }
                else
                {
                    await BinaryReaderWriter.ReadExactly(count, fromStream, intoBuffer, cancellationToken);
                }
            }
            catch (InternalBufferOverflowException e)
            {
                throw new InternalBufferOverflowException($"Supplied buffer too small to read {0} bytes from {Enum.GetName(typeof(WebSocketOpCode), opCode)} frame", e);
            }

            if (opCode == WebSocketOpCode.ConnectionClose)
            {
                return(DecodeCloseFrame(isFinBitSet, opCode, count, intoBuffer));
            }
            else
            {
                // note that by this point the payload will be populated
                return(new WebSocketFrame(isFinBitSet, opCode, count));
            }
        }
示例#23
0
 public void ReceivePayload(Socket ClientSocket)
 {
     byte[] PayloadBuffer = new byte[HeaderFrame.PayloadLength];
     ClientSocket.Receive(PayloadBuffer);
     for (int i = 0; i < PayloadBuffer.Length; i++)
     {
         PayloadBuffer[i] = (byte)(PayloadBuffer[i] ^ HeaderFrame.MaskKey[i % 4]);
     }
     PayloadData   = Encoding.UTF8.GetString(PayloadBuffer);
     PayloadOpCode = HeaderFrame.OpCode;
 }
        public WebSocketFrame Read(Stream stream, Socket socket)
        {
            byte byte1;

            try
            {
                byte1 = (byte)stream.ReadByte();
            }
            catch (IOException)
            {
                if (socket.Connected)
                {
                    throw;
                }
                else
                {
                    return(null);
                }
            }

            // process first byte
            byte            finBitFlag  = 0x80;
            byte            opCodeFlag  = 0x0F;
            bool            isFinBitSet = (byte1 & finBitFlag) == finBitFlag;
            WebSocketOpCode opCode      = (WebSocketOpCode)(byte1 & opCodeFlag);

            // read and process second byte
            byte byte2        = (byte)stream.ReadByte();
            byte maskFlag     = 0x80;
            bool isMaskBitSet = (byte2 & maskFlag) == maskFlag;
            uint len          = ReadLength(byte2, stream);

            byte[] payload;

            // use the masking key to decode the data if needed
            if (isMaskBitSet)
            {
                byte[] maskKey = BinaryReaderWriter.ReadExactly(WebSocketFrameCommon.MaskKeyLength, stream);
                payload = BinaryReaderWriter.ReadExactly((int)len, stream);

                // apply the mask key to the payload (which will be mutated)
                WebSocketFrameCommon.ToggleMask(maskKey, payload);
            }
            else
            {
                payload = BinaryReaderWriter.ReadExactly((int)len, stream);
            }

            WebSocketFrame frame = new WebSocketFrame(isFinBitSet, opCode, payload, true);

            return(frame);
        }
示例#25
0
    public void SendFrames(List <string> Data, WebSocketOpCode OpCode)
    {
        // Skicka initiella framen
        SendFrame(Data[0], OpCode, false);

        for (int i = 1; i < Data.Count - 1; i++)
        {
            SendFrame(Data[i], WebSocketOpCode.ContinuationFrame, false);
        }

        //Skicka sista framen
        SendFrame(Data[Data.Count - 1], WebSocketOpCode.ContinuationFrame, true);
    }
示例#26
0
 protected virtual void Send(WebSocketOpCode opCode, byte[] toSend, bool isLastFrame)
 {
     if (_isOpen)
     {
         lock (_sendLocker)
         {
             if (_isOpen)
             {
                 _writer.Write(opCode, toSend, isLastFrame);
             }
         }
     }
 }
示例#27
0
 protected override void Send(WebSocketOpCode opCode, byte[] toSend, bool isLastFrame)
 {
     if (!IsConnected)
     {
         OnError(this, new ErrorEventArgs((Int32)SocketError.NotConnected, string.Format("Connection not available for  {0} {1} ", _channelParameters.IP, _channelParameters.Port)));
         return;
     }
     byte[] buffer = _frameBuilder.GetFrameBytesFromData(opCode, toSend, isLastFrame);
     if (_socketHandler != null)
     {
         _socketHandler.Send(buffer);
     }
 }
示例#28
0
 protected virtual void Send(WebSocketOpCode opCode, byte[] toSend, bool isLastFrame)
 {
     if (_isOpen)
     {
         //_logger.Information(this.GetType(), "WebsocketBase:Send() sending information");
         lock (_sendLocker)
         {
             if (_isOpen)
             {
                 _writer.Write(opCode, toSend, isLastFrame);
             }
         }
     }
 }
示例#29
0
        public void ParsePayload(WebSocketFlags fl, WebSocketOpCode op, bool mask, UInt64 len, byte[] maskkey, byte[] payload)
        {
            Flags         = fl;
            OpCode        = op;
            Mask          = mask;
            PayloadLength = len;
            MaskingKey    = maskkey;
            Payload       = payload;

            if (Mask && Payload != null)
            {
                MaskPayload(); //unmask
            }
        }
        /// <summary>
        /// No async await stuff here because we are dealing with a memory stream
        /// </summary>
        /// <param name="opCode">The web socket opcode</param>
        /// <param name="fromPayload">Array segment to get payload data from</param>
        /// <param name="toStream">Stream to write to</param>
        /// <param name="isLastFrame">True is this is the last frame in this message (usually true)</param>
        public static void Write(WebSocketOpCode opCode, ArraySegment <byte> fromPayload, MemoryStream toStream, bool isLastFrame, bool isClient)
        {
            MemoryStream memoryStream    = toStream;
            byte         finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00;
            byte         byte1           = (byte)(finBitSetAsByte | (byte)opCode);

            memoryStream.WriteByte(byte1);

            // NB, set the mask flag if we are constructing a client frame
            byte maskBitSetAsByte = isClient ? (byte)0x80 : (byte)0x00;

            // depending on the size of the length we want to write it as a byte, ushort or ulong
            if (fromPayload.Count < 126)
            {
                byte byte2 = (byte)(maskBitSetAsByte | (byte)fromPayload.Count);
                memoryStream.WriteByte(byte2);
            }
            else if (fromPayload.Count <= ushort.MaxValue)
            {
                byte byte2 = (byte)(maskBitSetAsByte | 126);
                memoryStream.WriteByte(byte2);
                BinaryReaderWriter.WriteUShort((ushort)fromPayload.Count, memoryStream, false);
            }
            else
            {
                byte byte2 = (byte)(maskBitSetAsByte | 127);
                memoryStream.WriteByte(byte2);
                BinaryReaderWriter.WriteULong((ulong)fromPayload.Count, memoryStream, false);
            }

            // if we are creating a client frame then we MUST mack the payload as per the spec
            if (isClient)
            {
                byte[] maskKey = new byte[WebSocketFrameCommon.MaskKeyLength];
                _random.NextBytes(maskKey);
                memoryStream.Write(maskKey, 0, maskKey.Length);

                // mask the payload
                var maskKeyArraySegment = new ArraySegment <byte>(maskKey, 0, maskKey.Length);
                WebSocketFrameCommon.ToggleMask(maskKeyArraySegment, fromPayload);
                memoryStream.Write(fromPayload.Array, fromPayload.Offset, fromPayload.Count);
                // unmask it so we don't destroy user's data
                WebSocketFrameCommon.ToggleMask(maskKeyArraySegment, fromPayload);
                return;
            }

            memoryStream.Write(fromPayload.Array, fromPayload.Offset, fromPayload.Count);
        }
示例#31
0
        public void Write(WebSocketOpCode opCode, byte[] payload, bool isLastFrame)
        {
            // best to write everything to a memory stream before we push it onto the wire
            // not really necessary but I like it this way
            using (MemoryStream memoryStream = new MemoryStream())
            {
                byte finBitSetAsByte = isLastFrame ? (byte)0x80 : (byte)0x00;
                byte byte1           = (byte)(finBitSetAsByte | (byte)opCode);
                memoryStream.WriteByte(byte1);

                // NB, set the mask flag if we are constructing a client frame
                byte maskBitSetAsByte = _isClient ? (byte)0x80 : (byte)0x00;

                // depending on the size of the length we want to write it as a byte, ushort or ulong
                if (payload.Length < 126)
                {
                    byte byte2 = (byte)(maskBitSetAsByte | (byte)payload.Length);
                    memoryStream.WriteByte(byte2);
                }
                else if (payload.Length <= ushort.MaxValue)
                {
                    byte byte2 = (byte)(maskBitSetAsByte | 126);
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteUShort((ushort)payload.Length, memoryStream, false);
                }
                else
                {
                    byte byte2 = (byte)(maskBitSetAsByte | 127);
                    memoryStream.WriteByte(byte2);
                    BinaryReaderWriter.WriteULong((ulong)payload.Length, memoryStream, false);
                }

                // if we are creating a client frame then we MUST mack the payload as per the spec
                if (_isClient)
                {
                    byte[] maskKey = new byte[WebSocketFrameCommon.MaskKeyLength];
                    _random.NextBytes(maskKey);
                    memoryStream.Write(maskKey, 0, maskKey.Length);

                    // mask the payload
                    WebSocketFrameCommon.ToggleMask(maskKey, payload);
                }

                memoryStream.Write(payload, 0, payload.Length);
                byte[] buffer = memoryStream.ToArray();
                _stream.Write(buffer, 0, buffer.Length);
            }
        }
示例#32
0
        internal void Send(WebSocketOpCode opCode, byte[] payloadBytes, bool disconnectionInProgress)
        {
            try
            {
                // Start creating a WebSocket packet
                const int DefaultCapacity = 64;
                var       result          = new List <byte>(DefaultCapacity);
                result.Add((byte)(128 | (byte)opCode));

                // Add the payload bytes to the WebSocket packet, prefixed with a properly encoded length
                if (payloadBytes.Length <= 125)
                {
                    result.Add((byte)payloadBytes.Length);
                }
                if (payloadBytes.Length > 125 && payloadBytes.Length <= ushort.MaxValue)
                {
                    result.Add(126);
                    var interim = BitConverter.GetBytes((ushort)payloadBytes.Length);
                    Array.Reverse(interim);
                    result.AddRange(interim);
                }
                if (payloadBytes.Length > ushort.MaxValue)
                {
                    result.Add(127);
                    var interim = BitConverter.GetBytes((ulong)payloadBytes.Length);
                    Array.Reverse(interim);
                    result.AddRange(interim);
                }
                result.AddRange(payloadBytes);

                // Send the data
                Socket.Send(result.ToArray());
            }
            catch (Exception ex)
            {
                // Make one attempt to nicely disconnect the socket and raise a disconnection packet
                if (!disconnectionInProgress)
                {
                    Disconnect(4000, ex.Message);
                    var disconnectionPacket = new Packet(RemoteEndPoint, WebSocketAction.Disconnect, ex.Message);
                    PacketReceived?.Invoke(disconnectionPacket);
                }
            }
        }
        private void MainReadLoop()
        {
            NetworkStream networkStream = _networkStream;
            WebSocketFrameReader reader = new WebSocketFrameReader();
            List<WebSocketFrame> fragmentedFrames = new List<WebSocketFrame>();

            while (true)
            {
                WebSocketFrame frame = reader.Read(networkStream);

                // if we have received unexpected data
                if (!frame.IsValid)
                {
                    return;
                }

                if (frame.OpCode == WebSocketOpCode.ContinuationFrame)
                {
                    switch (_multiFrameOpcode)
                    {
                        case WebSocketOpCode.TextFrame:
                            String data = Encoding.UTF8.GetString(frame.DecodedPayload, 0, frame.DecodedPayload.Length);
                            OnTextMultiFrame(data, frame.IsFinBitSet);
                            break;
                        case WebSocketOpCode.BinaryFrame:
                            OnBinaryMultiFrame(frame.DecodedPayload, frame.IsFinBitSet);
                            break;
                    }
                }
                else
                {
                    switch (frame.OpCode)
                    {
                        case WebSocketOpCode.ConnectionClose:
                            OnConnectionClosed(frame.DecodedPayload);
                            return;
                        case WebSocketOpCode.Ping:
                            OnPing(frame.DecodedPayload);
                            break;
                        case WebSocketOpCode.TextFrame:
                            String data = Encoding.UTF8.GetString(frame.DecodedPayload, 0, frame.DecodedPayload.Length);
                            if (frame.IsFinBitSet)
                            {
                                OnTextFrame(data);
                            }
                            else
                            {
                                _multiFrameOpcode = frame.OpCode;
                                OnTextMultiFrame(data, frame.IsFinBitSet);
                            }
                            break;
                        case WebSocketOpCode.BinaryFrame:
                            if (frame.IsFinBitSet)
                            {
                                OnBinaryFrame(frame.DecodedPayload);
                            }
                            else
                            {
                                _multiFrameOpcode = frame.OpCode;
                                OnBinaryMultiFrame(frame.DecodedPayload, frame.IsFinBitSet);
                            }
                            break;
                    }
                }
            }
        }
示例#34
0
        private bool ReadStart(BinaryReader reader)
        {
            if (reader.BaseStream.Length < 2)
                return (false);

            var data = reader.ReadByte();

            var nibble2 = (byte)(data & 0x0F);
            var nibble1 = (byte)(data & 0xF0);

            if ((nibble1 & EndBit) == EndBit)
                IsEnd = true;

            data = reader.ReadByte();

            PayloadSize = (byte)(data & 0x7F);
            IsMasked = (byte)(data & 0x80) > 0;
            OpCode = (WebSocketOpCode)nibble2;
            return (true);
        }
 public void Write(WebSocketOpCode opCode, byte[] payload)
 {
     Write(opCode, payload, true);
 }
        /// <summary>
        /// Read web socket frame info
        /// </summary>
        /// <param name="buffer">received buffer</param>
        /// <param name="offset">received offset</param>
        /// <param name="isFin">is message fin</param>
        /// <param name="isRSVNull">is all three RSV bits false</param>
        /// <param name="opCode">operation code</param>
        /// <param name="isMasked">is payLoadDataMasked (for message from client
        /// always true, for message from server always false</param>
        /// <param name="maskBegin">mask begin byte number</param>
        /// <param name="length">full message length</param>
        /// <returns>Is whole message received</returns>
        private static bool GetFrameInfo(byte[] buffer, int offset, int remainingBytesToProcess, out bool isFin, out bool isRSVNull, out WebSocketOpCode opCode, out bool isMasked, out int maskBegin, out int length)
        {
            //   From specification
            //   0                   1                   2                   3
            //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
            //   +-+-+-+-+-------+-+-------------+-------------------------------+
            //   |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
            //   |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
            //   |N|V|V|V|       |S|             |   (if payload len==126/127)   |
            //   | |1|2|3|       |K|             |                               |
            //   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
            //   |     Extended payload length continued, if payload len == 127  |
            //   + - - - - - - - - - - - - - - - +-------------------------------+
            //   |                               |Masking-key, if MASK set to 1  |
            //   +-------------------------------+-------------------------------+
            //   | Masking-key (continued)       |          Payload Data         |
            //   +-------------------------------- - - - - - - - - - - - - - - - +
            //   :                     Payload Data continued ...                :
            //   + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
            //   |                     Payload Data continued ...                |
            //   +---------------------------------------------------------------+

            isFin = BitOperations.GetBitFromByte(buffer[offset], 8);
            isRSVNull = (buffer[offset] & 0x70) == 0x00;
            opCode = (WebSocketOpCode)(buffer[offset] & 0xF);
            isMasked = BitOperations.GetBitFromByte(buffer[offset + 1], 8);
            var payLoadLength = buffer[offset + 1] & 0x7F;
            maskBegin = 2;
            if (payLoadLength == 0x7E)
            {
                payLoadLength = BitConverter.ToUInt16(buffer, offset + 2);
                maskBegin = 4;
            }
            if (payLoadLength == 0x7F)
            {
                //IMPORTANT! Converting ulong to int for simplify,
                //for long data doesn't work!
                payLoadLength = (int)BitConverter.ToUInt64(buffer, offset + 4);
                maskBegin = 10;
            }
            //4 is a mask length
            length = maskBegin + payLoadLength + 4;
            return remainingBytesToProcess >= length;
        }
示例#37
0
 internal DataFrame(byte[] payload, WebSocketOpCode opcode)
 {
     this.Payload = payload;
     this.OpCode = opcode;
 }