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); }
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); }
/// <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); }
/// <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)); } } }
/// <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)); } } }
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); } }