Пример #1
0
 public void HandleChunked(byte[] bodyPart = null)
 {
     if (bodyPart == null)
     {
         int readFromStream = serverStream.Read(buffer, 0, BufferSize);
         ReadAndSendBytes(buffer.Take(readFromStream).ToArray());
     }
     else
     {
         ReadAndSendBytes(bodyPart);
     }
 }
        public static INetworkMessage ReadMessage(INetworkStream stream)
        {
            var intBytes  = stream.Read(0, 4);
            var messageId = BitConverter.ToInt32(intBytes, 0);

            intBytes = stream.Read(0, 4);
            var payloadLength = BitConverter.ToInt32(intBytes, 0);

            intBytes = stream.Read(0, 4);
            var messageType = BitConverter.ToInt32(intBytes, 0);

            var payloadBytes = stream.Read(0, payloadLength);

            return(BuildMessage(messageId, messageType, payloadBytes));
        }
Пример #3
0
        private void ReadAndWrite(byte[] buffer, int size)
        {
            if (!serverStream.DataAvailable)
            {
                return;
            }

            int readFromStream = serverStream.Read(buffer, 0, size);

            WriteOnStream(buffer, readFromStream);
        }
        public IReadOnlyList <IMessage> ReadAvailable()
        {
            bool hasRead = false;

            if (inputStream.DataAvailable)
            {
                int read = inputStream.Read(buffer, bufferPos, buffer.Length - bufferPos);
                bufferPos += read;
                hasRead    = read > 0;
            }

            if (!inputStream.Connected || hasRead)
            {
                return(ReadMessages());
            }
            return(EmptyList);
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="requests">Requests to send</param>
        /// <returns>Responses from the server</returns>
        public Message[] SendRequests(Message[] requests)
        {
            byte[] requestsBytes;
            int    count = _converter.MessagesToBytes(out requestsBytes, requests);

            ITcpClient _tcpClient = _tcpFactory.Create();

            _tcpClient.Connect(_address, _port);
            using (INetworkStream networkStream = _tcpClient.GetStream())
            {
                networkStream.Write(requestsBytes, count);
                byte[] responseBytes = new byte[Properties.Settings.Default.MaxBufferSize];
                int    len           = networkStream.Read(responseBytes, Properties.Settings.Default.MaxBufferSize);
                networkStream.Close();
                _tcpClient.Close();
                return(_converter.BytesToMessages(responseBytes, len));
            }
        }
Пример #6
0
        public byte[] Read()
        {
            // Once execution reached this point it means that connection with Server is established
            // Now we can try to read incoming stream
            if (serverNetworkStream != null)
            {
                var bytesRead = serverNetworkStream.Read(dataBytes, 0, dataBytes.Length);

                if (bytesRead == 0)
                {
                    Thread.Sleep(10);
                }
                else
                {
                    // Process the data received from the socket
                    TransportDataReceived?.Invoke(this, serverNetworkStream.ReadBuffer.Take(bytesRead).ToArray());
                }
            }

            return(dataBytes);
        }
        public IMessage ReadAvailable()
        {
            stream.Timeout = Timeout;

            try
            {
                int read;
                while ((read = stream.Read(buffer, bufferPos, buffer.Length - bufferPos)) > 0)
                {
                    bufferPos += read;
                    if (TryToDeserialize())
                    {
                        return(message);
                    }
                }
            }
            catch (Exception)
            {
                throw new CannotReadMessageException();
            }

            throw new CannotReadMessageException();
        }
Пример #8
0
        /// <summary>
        /// Update the local data buffer with data from the remote network stream.
        /// </summary>
        protected virtual void Update()
        {
            int totalBytesRead = 0;

            do
            {
                int bytesRead = _stream.Read(_internalBuffer, 0, _internalBuffer.Length);
                if (bytesRead == 0)
                {
                    throw new System.IO.IOException("The underlying socket has been closed.");
                }

                // lock so we're not appending to and reading from the buffer at the same time
                lock (BufferLock)
                {
                    _readBuffer.Append(Encoding.ASCII.GetChars(_internalBuffer, 0, bytesRead));
                }

                totalBytesRead += bytesRead;
            }while (_stream.DataAvailable);
            // send data received event
            OnDataLengthReceived(new DataLengthEventArgs(totalBytesRead));
            if (DebugReceiveBuffer && !String.IsNullOrEmpty(DebugBufferFileName))
            {
                try
                {
                    System.IO.File.AppendAllText(DebugBufferFileName,
                                                 _readBuffer.ToString().Replace("\n", Environment.NewLine).Replace("\\n", Environment.NewLine));
                }
                catch (Exception ex)
                {
                    OnStatusMessage(new StatusMessageEventArgs(String.Format(CultureInfo.CurrentCulture,
                                                                             "Debug buffer write failed: {0}", ex.Message), TraceLevel.Error));
                }
            }
        }
Пример #9
0
        private void TcpipThreadListener()
        {
            serverThreadRunningFlag = true;
            tryConnectingFlag       = true;
            byte[] bytesFrom = new byte[10025];

            while (serverThreadRunningFlag)
            {
                while (tryConnectingFlag)
                {
                    try
                    {
                        if (clientSocket == null)
                        {
                            clientSocket = new TcpClient();
                        }

                        clientSocket.Connect(addressIp, portNumber);
                        serverNetworkStream    = new TcpNetworkStream(clientSocket?.GetStream());
                        tryConnectingFlag      = false;
                        tcpipThreadRunningFlag = true;
                    }
                    catch (ObjectDisposedException)
                    {
                        tryConnectingFlag = true;
                    }
                    catch (SocketException)
                    {
                        tryConnectingFlag = true;
                    }
                }

                // Once execution reached this point it means that connection with Server is established
                // Now we can try to read incoming stream
                int bytesRead = -1;

                try
                {
                    // Notice: The line below executes ONLY after bytesFrom will have something in it
                    // which is achieved by a "Bond" or "Start Sampling all RS" on the Server app.
                    if (serverNetworkStream != null)
                    {
                        bytesRead = serverNetworkStream.Read(bytesFrom, 0, bytesFrom.Length);

                        if (bytesRead == 0)
                        {
                            Thread.Sleep(10);
                        }
                        else
                        {
                            // Process the data received from the socket
                            TransportDataReceived?.Invoke(this, bytesFrom);
                        }
                    }

                    Thread.Sleep(10);
                }
                catch (IOException ex)
                {
                    Cleanup(ex);
                    break;
                }
                catch (ObjectDisposedException ex)
                {
                    Cleanup(ex);
                    break;
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Asynchronous task for decoding frames off the networking stream. The method calls _receiveFrame for each frame received
        /// which determines what to do with it based on the current Connection state, frame type, and frame contents
        /// </summary>
        /// <param name="stream">The network stream from which frames will be decoded</param>
        /// <param name="ct">Cancellation token</param>
        /// <returns>The asynchronous task</returns>
        private Task _decodeStreamAsync(INetworkStream stream, CancellationToken ct)
        {
            return(Task.Run(() =>
            {
                var frameSizeUsed = Frame.MaxFrameSize;
                byte[] buffer = new byte[Frame.MaxFrameSize * 3];
                int bufferOffset = 0;
                int availableBytes = 0;

                while (!ct.IsCancellationRequested && State != ConnectionState.End && State != ConnectionState.ConnectionError)
                {
                    int read = 0;
                    while ((read = stream.Read(buffer, bufferOffset + availableBytes, buffer.Length - (bufferOffset + availableBytes))) > 0)
                    {
                        availableBytes += read;

                        var frames = Frame.DecodeFrameBuffer(buffer, bufferOffset, availableBytes, out bufferOffset, out availableBytes);
                        foreach (var frame in frames)
                        {
                            // pass for processing
                            _processFrame(frame);
                        }

                        // shift any remaining data to the beginning of the buffer
                        if (bufferOffset > 0 && availableBytes > 0)
                        {
                            Log.DebugFormat("[{0}] Moving remaining bytes to beginning of buffer: Offset [{1}], Available [{2}]", ID, bufferOffset, availableBytes);

                            Array.Copy(buffer, bufferOffset, buffer, 0, availableBytes);
                            bufferOffset = 0;
                        }

                        if (frameSizeUsed != Frame.MaxFrameSize)
                        {
                            Log.DebugFormat("[{0}] Resizing frame buffer: Current [{1}], New [{2}]", ID, frameSizeUsed, Frame.MaxFrameSize);

                            // the protocol negotiation has adjusted the frame size - resize buffer
                            var resizedBuffer = new byte[Frame.MaxFrameSize * 3];
                            Array.Copy(buffer, bufferOffset, resizedBuffer, 0, availableBytes);
                            buffer = resizedBuffer;
                            bufferOffset = 0;
                            frameSizeUsed = Frame.MaxFrameSize;
                        }
                    }
                }
            }).ContinueWith(t =>
            {
                if (t.Exception != null)
                {
                    // change state to error
                    State = ConnectionState.ConnectionError;

                    // close dependent components and resources
                    _closeInternal();

                    // raise error event
                    OnError?.Invoke(this, null);
                }

                Log.DebugFormat("Decode stream task has ended");
            }));
        }
        //------------------------------------------------------------------------------
        //
        // Method: ReadAndParseMessageData
        //
        //------------------------------------------------------------------------------
        /// <summary>
        /// Reads bytes from the inputted network stream and parses them, storing the results in the inputted parameters.
        /// </summary>
        /// <param name="networkStream">The network stream to read data from.</param>
        /// <param name="parseState">Represents the current state of parsing.</param>
        /// <param name="messageSequenceNumberBytes">The bytes containing the message sequence number.</param>
        /// <param name="messageSequenceNumberCurrentPosition">The current read position within the message sequence number bytes.</param>
        /// <param name="messageSequenceNumber">The message sequence number.</param>
        /// <param name="messageSizeHeaderBytes">The header bytes containing the message size.</param>
        /// <param name="messageSizeHeaderCurrentPosition">The current read position within the message size header bytes.</param>
        /// <param name="messageSize">The size of the message body.</param>
        /// <param name="messageBytes">The bytes containing the message body.</param>
        private void ReadAndParseMessageData(INetworkStream networkStream, ref MessageParseState parseState, byte[] messageSequenceNumberBytes, ref int messageSequenceNumberCurrentPosition, ref int messageSequenceNumber, byte[] messageSizeHeaderBytes, ref int messageSizeHeaderCurrentPosition, ref long messageSize, Queue <byte> messageBytes)
        {
            int availableBytes = client.Available;

            if (availableBytes > 0)
            {
                byte[] tempBuffer = new byte[availableBytes];  // Temporary buffer to store bytes read from the network before parsing
                networkStream.Read(ref tempBuffer, 0, availableBytes);

                // Iterate through the bytes in the buffer, advancing the parse state as successive sections (i.e. start delimiter, sequence number, size header, body, etc...) are read
                for (int i = 0; i < tempBuffer.Length; i = i + 1)
                {
                    switch (parseState)
                    {
                    case MessageParseState.StartOfMessage:
                        if (tempBuffer[i] != messageStartDelimiter)
                        {
                            throw new Exception("First byte of received message was expected to be " + messageStartDelimiter.ToString() + ", but was " + tempBuffer[i].ToString() + ".");
                        }
                        else
                        {
                            parseState = MessageParseState.ReadStartDelimiter;
                        }
                        break;

                    case MessageParseState.ReadStartDelimiter:
                        messageSequenceNumberBytes[messageSequenceNumberCurrentPosition] = tempBuffer[i];
                        messageSequenceNumberCurrentPosition++;
                        // If 4 bytes have been read into the sequence number byte array, then set the sequence number, and advance to the next parse state
                        if (messageSequenceNumberCurrentPosition == 4)
                        {
                            // Decode as little endian
                            if (BitConverter.IsLittleEndian == false)
                            {
                                Array.Reverse(messageSequenceNumberBytes);
                            }
                            messageSequenceNumber = BitConverter.ToInt32(messageSequenceNumberBytes, 0);
                            parseState            = MessageParseState.ReadSequenceNumber;
                        }
                        break;

                    case MessageParseState.ReadSequenceNumber:
                        messageSizeHeaderBytes[messageSizeHeaderCurrentPosition] = tempBuffer[i];
                        messageSizeHeaderCurrentPosition++;
                        // If 8 bytes have been read into the message size header byte array, then set the message size, and advance to the next parse state
                        if (messageSizeHeaderCurrentPosition == 8)
                        {
                            // Decode as little endian
                            if (BitConverter.IsLittleEndian == false)
                            {
                                Array.Reverse(messageSizeHeaderBytes);
                            }
                            messageSize = BitConverter.ToInt64(messageSizeHeaderBytes, 0);
                            parseState  = MessageParseState.ReadSizeHeader;
                        }
                        break;

                    case MessageParseState.ReadSizeHeader:
                        messageBytes.Enqueue(tempBuffer[i]);
                        // If the number of bytes read matches the size specified in the header, advance to the next parse state
                        if (messageBytes.Count == messageSize)
                        {
                            parseState = MessageParseState.ReadMessageBody;
                        }
                        break;

                    case MessageParseState.ReadMessageBody:
                        if (tempBuffer[i] != messageEndDelimiter)
                        {
                            throw new Exception("Last byte of received message was expected to be " + messageEndDelimiter.ToString() + ", but was " + tempBuffer[i].ToString() + ".");
                        }
                        else
                        {
                            parseState = MessageParseState.ReadCompleteMessage;
                        }
                        break;

                    case MessageParseState.ReadCompleteMessage:
                        throw new Exception("Surplus data encountered after message delimiter character, starting with " + tempBuffer[i].ToString() + ".");
                    }
                }
            }
        }