示例#1
0
 private void OnAccept(IAsyncResult result)
 {
     try
     {
         TcpClient sock = mListener.EndAcceptTcpClient(result);
         ReadWrapper RW = new ReadWrapper(sock, new byte[32768]);
         RW.s.ReadAsync(RW.buffer, 0, RW.buffer.Length).ContinueWith((Action<Task<int>, object>)OnRead, RW);
     }
     catch { }
     mListener.BeginAcceptSocket(OnAccept, null);
 }
示例#2
0
 private void OnAccept(IAsyncResult result)
 {
     try
     {
         TcpClient   sock = mListener.EndAcceptTcpClient(result);
         ReadWrapper RW   = new ReadWrapper(sock, new byte[32768]);
         RW.s.ReadAsync(RW.buffer, 0, RW.buffer.Length).ContinueWith((Action <Task <int>, object>)OnRead, RW);
     }
     catch { }
     mListener.BeginAcceptSocket(OnAccept, null);
 }
示例#3
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="MqttConnection" /> class.
        /// </summary>
        /// <param name="server">The server.</param>
        /// <param name="port">The port.</param>
        private MqttConnection(string server, int port) {
            try {
                Log.Debug(m => m("Connecting to message broker running on {0}:{1}", server, port));
                // connect and save off the stream.
                tcpClient = new TcpClient(server, port);
            } catch (SocketException ex) {
                String message = String.Format("The connection to the message broker {0}:{1} could not be made.", server, port);
                Log.Error(message, ex);
                throw new ConnectionException(message, ConnectionState.Faulted, ex);
            }

            // get and stash the network stream
            var readWrapper = new ReadWrapper(tcpClient.GetStream());
            readWrapper.Stream.BeginRead(readWrapper.Buffer, 0, readWrapper.NextReadSize, ReadHeaderComplete, readWrapper);
        }
示例#4
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="MqttConnection" /> class.
        /// </summary>
        /// <param name="server">The server.</param>
        /// <param name="port">The port.</param>
        private MqttConnection(string server, int port)
        {
            try {
                Log.Debug(m => m("Connecting to message broker running on {0}:{1}", server, port));
                // connect and save off the stream.
                tcpClient = new TcpClient(server, port);
            } catch (SocketException ex) {
                String message = String.Format("The connection to the message broker {0}:{1} could not be made.", server, port);
                Log.Error(message, ex);
                throw new ConnectionException(message, ConnectionState.Faulted, ex);
            }

            // get and stash the network stream
            var readWrapper = new ReadWrapper(tcpClient.GetStream());

            readWrapper.Stream.BeginRead(readWrapper.Buffer, 0, readWrapper.NextReadSize, ReadHeaderComplete, readWrapper);
        }
示例#5
0
        /// <summary>
        ///     Callback for when data has been read from the underlying network stream.
        /// </summary>
        /// <param name="asyncResult">The async result from the read.</param>
        private void ReadHeaderComplete(IAsyncResult asyncResult)
        {
            var readWrapper = (ReadWrapper)asyncResult.AsyncState;

            try {
                var bytesRead = readWrapper.Stream.EndRead(asyncResult);
                if (bytesRead == 0)
                {
                    // Nothing read, we will just try another read from the stream.
                    Log.Debug("Async network stream read returned 0 bytes, continuing to search for header.");
                    readWrapper.ReadState = ConnectionReadState.Header;
                }
                else if (tcpClient.Connected && readWrapper.Stream.CanRead)
                {
                    if (readWrapper.ReadState == ConnectionReadState.Header && readWrapper.Stream.DataAvailable)
                    {
                        Log.Info("Reading message arriving on the wire.");

                        readWrapper.MessageBytes.Add(readWrapper.Buffer[0]);

                        var lengthBytes     = MqttHeader.ReadLengthBytes(readWrapper.Stream);
                        var remainingLength = MqttHeader.CalculateLength(lengthBytes);

                        // update the read wrapper with the header bytes, and a resized read buffer
                        // to capture the remaining length.
                        readWrapper.MessageBytes.AddRange(lengthBytes);

                        // no content, so yield the message early, else transition to reading the content.
                        if (remainingLength == 0)
                        {
                            Log.Debug("Message receipt complete. Has empty content length so handing off now.");
                            FireDataAvailableEvent(readWrapper.MessageBytes);
                        }
                        else
                        {
                            // total bytes of content is the remaining length plus the header.
                            readWrapper.TotalBytes = remainingLength + readWrapper.MessageBytes.Count;
                            readWrapper.RecalculateNextReadSize();
                            readWrapper.ReadState = ConnectionReadState.Content;
                        }
                    }
                    else if (readWrapper.ReadState == ConnectionReadState.Content)
                    {
                        // stash what we've read.
                        readWrapper.MessageBytes.AddRange(readWrapper.Buffer.Take(bytesRead));
                        Log.Debug(m => m("Message Content read {0:n0} of {1:n0} expected remaining bytes.", bytesRead, readWrapper.TotalBytes));

                        // if we haven't yet read all of the message repeat the read otherwise if
                        // we're finished process the message and switch back to waiting for the next header.
                        if (readWrapper.IsReadComplete)
                        {
                            // reset the read buffer to accommodate the remaining length (last - what was read)
                            readWrapper.RecalculateNextReadSize();
                        }
                        else
                        {
                            Log.Debug(m => m("Message receipt complete ({0:n0} total bytes including all headers), handing off to handlers.", readWrapper.MessageBytes.Count));
                            readWrapper.ReadState = ConnectionReadState.Header;
                            FireDataAvailableEvent(readWrapper.MessageBytes);
                        }
                    }

                    // if we've switched to reading a header then recreate the read dwrapper for the next message
                    if (readWrapper.ReadState == ConnectionReadState.Header)
                    {
                        readWrapper = new ReadWrapper(readWrapper.Stream);
                    }
                    // we can still read etc
                    // initiate a read for the next set of bytes which will be the header bytes so long as
                    // we're still connected to the underlying client
                    readWrapper.Stream.BeginRead(readWrapper.Buffer, 0, readWrapper.NextReadSize, ReadHeaderComplete, readWrapper);
                }
            } catch (IOException ex) {
                Log.Debug("Error occurred during async read from broker network stream. Initiating broker disconnect", ex);

                // close the underlying connection
                this.Disconnect();

                if (ConnectionDropped != null)
                {
                    ConnectionDropped(this, new ConnectionDroppedEventArgs(ex));
                }
            }
        }
示例#6
0
        /// <summary>
        ///     Callback for when data has been read from the underlying network stream.
        /// </summary>
        /// <param name="asyncResult">The async result from the read.</param>
        private void ReadHeaderComplete(IAsyncResult asyncResult) {
            var readWrapper = (ReadWrapper) asyncResult.AsyncState;

            try {
                var bytesRead = readWrapper.Stream.EndRead(asyncResult);
                if (bytesRead == 0) {
                    // Nothing read, we will just try another read from the stream.
                    Log.Debug("Async network stream read returned 0 bytes, continuing to search for header.");
                    readWrapper.ReadState = ConnectionReadState.Header;
                } else if (tcpClient.Connected && readWrapper.Stream.CanRead) {
                    if (readWrapper.ReadState == ConnectionReadState.Header && readWrapper.Stream.DataAvailable) {
                        Log.Info("Reading message arriving on the wire.");

                        readWrapper.MessageBytes.Add(readWrapper.Buffer[0]);

                        var lengthBytes = MqttHeader.ReadLengthBytes(readWrapper.Stream);
                        var remainingLength = MqttHeader.CalculateLength(lengthBytes);

                        // update the read wrapper with the header bytes, and a resized read buffer
                        // to capture the remaining length.
                        readWrapper.MessageBytes.AddRange(lengthBytes);

                        // no content, so yield the message early, else transition to reading the content.
                        if (remainingLength == 0) {
                            Log.Debug("Message receipt complete. Has empty content length so handing off now.");
                            FireDataAvailableEvent(readWrapper.MessageBytes);
                        } else {
                            // total bytes of content is the remaining length plus the header.
                            readWrapper.TotalBytes = remainingLength + readWrapper.MessageBytes.Count;
                            readWrapper.RecalculateNextReadSize();
                            readWrapper.ReadState = ConnectionReadState.Content;
                        }
                    } else if (readWrapper.ReadState == ConnectionReadState.Content) {
                        // stash what we've read.
                        readWrapper.MessageBytes.AddRange(readWrapper.Buffer.Take(bytesRead));
                        Log.Debug(m => m("Message Content read {0:n0} of {1:n0} expected remaining bytes.", bytesRead, readWrapper.TotalBytes));

                        // if we haven't yet read all of the message repeat the read otherwise if
                        // we're finished process the message and switch back to waiting for the next header.
                        if (readWrapper.IsReadComplete) {
                            // reset the read buffer to accommodate the remaining length (last - what was read)
                            readWrapper.RecalculateNextReadSize();
                        } else {
                            Log.Debug(m => m("Message receipt complete ({0:n0} total bytes including all headers), handing off to handlers.", readWrapper.MessageBytes.Count));
                            readWrapper.ReadState = ConnectionReadState.Header;                            
                            FireDataAvailableEvent(readWrapper.MessageBytes);
                        }
                    }

                    // if we've switched to reading a header then recreate the read dwrapper for the next message
                    if (readWrapper.ReadState == ConnectionReadState.Header) {
                        readWrapper = new ReadWrapper(readWrapper.Stream);
                    }
                    // we can still read etc
                    // initiate a read for the next set of bytes which will be the header bytes so long as
                    // we're still connected to the underlying client
                    readWrapper.Stream.BeginRead(readWrapper.Buffer, 0, readWrapper.NextReadSize, ReadHeaderComplete, readWrapper);
                }
            } catch (IOException ex) {
                Log.Debug("Error occurred during async read from broker network stream. Initiating broker disconnect", ex);

                // close the underlying connection
                this.Disconnect();

                if (ConnectionDropped != null) {
                    ConnectionDropped(this, new ConnectionDroppedEventArgs(ex));
                }
            }
        }
示例#7
0
        private async void OnRead(Task <int> t, object j)
        {
            ReadWrapper RW = j as ReadWrapper;

            RW.totalRead += t.Result;

            if (RW.totalRead < 4)
            {
                RW.offset += t.Result;
                object jj = RW.s.ReadAsync(RW.buffer, RW.offset, RW.buffer.Length - RW.totalRead).ContinueWith((Action <Task <int>, object>)OnRead, RW);
                return;
            }

            int h   = BitConverter.ToInt32(RW.buffer, 0);
            int eoh = -1;

            string[] headers = new string[0];

            switch (h)
            {
            case GET_HEADER:
            case POST_HEADER:
                for (int i = 4; i < RW.totalRead; ++i)
                {
                    if (BitConverter.ToInt32(RW.buffer, i) == END_HEADER)
                    {
                        eoh = i; break;
                    }
                }
                if (eoh > 0)
                {
                    headers = UTF8Encoding.UTF8.GetString(RW.buffer, 0, RW.totalRead).Split(new string[] { "\r\n" }, StringSplitOptions.None);
                }
                break;

            default:
                break;
            }

            if (eoh > 0)
            {
                switch (h)
                {
                case GET_HEADER:
                    byte[] resp = await ProcessGet(RW.client.Client.LocalEndPoint as IPEndPoint, headers[0]).ConfigureAwait(false);

                    if (resp.Length > 0)
                    {
                        RW.s.Write(resp, 0, resp.Length);
                    }
                    RW.s.Close();
                    break;

                case POST_HEADER:
                    // Check for Content-Length
                    int contentLength = -1;
                    foreach (string header in headers)
                    {
                        if (header.IndexOf(":") > 0)
                        {
                            string headerName  = header.Substring(0, header.IndexOf(":")).Trim();
                            string headerValue = header.Substring(header.IndexOf(":") + 1).Trim();
                            if (headerName.ToUpper() == "CONTENT-LENGTH")
                            {
                                contentLength = (int.Parse(headerValue)); break;
                            }
                        }
                    }
                    if (contentLength > 0)
                    {
                        if (contentLength + eoh + 4 <= RW.totalRead)
                        {
                            byte[] postResp = await ProcessPost(headers[0], UTF8Encoding.UTF8.GetString(RW.buffer, eoh + 4, contentLength)).ConfigureAwait(false);

                            if (postResp.Length > 0)
                            {
                                RW.s.Write(postResp, 0, postResp.Length);
                            }
                            RW.s.Close();
                        }
                        else
                        {
                            RW.offset += t.Result;
                            object jj = RW.s.ReadAsync(RW.buffer, RW.offset, RW.buffer.Length - RW.totalRead).ContinueWith((Action <Task <int>, object>)OnRead, RW);
                        }
                    }
                    else
                    {
                        byte[] postResp = await ProcessPost(headers[0], null).ConfigureAwait(false);

                        if (postResp.Length > 0)
                        {
                            RW.s.Write(postResp, 0, postResp.Length);
                        }
                        RW.s.Close();
                    }
                    break;
                }
            }
            else
            {
                RW.offset += t.Result;
                object jj = RW.s.ReadAsync(RW.buffer, RW.offset, RW.buffer.Length - RW.totalRead).ContinueWith((Action <Task <int>, object>)OnRead, RW);
            }
        }