/// <summary> /// Entry point for post-exchange data received from the Tcp Socket /// </summary> private void OnDataReceived(DataReceivedEventArgs args) { if (args.Owner.Client.Equals(_clientSocket.Client)) { // retrieve and buffer the packet ProcessAndPush(_rcvBuffer, args.Owner.Data); // check for sequenced packets in the queue if (_rcvBuffer.Count > 0) { do { // process if in sequence or break if (!_rcvBuffer.Exists(_rcvSequence)) break; else Process(_rcvBuffer.Pop(_rcvSequence)); } while (true); } } }
/// <summary> /// The ReceiveAsync callback /// </summary> /// /// <param name="Ar">The IAsyncResult</param> /// /// <exception cref="CryptoSocketException">Thrown on socket error or if the Tcp stream is larger than the maximum allocation size</exception> private void ReceiveCallback(IAsyncResult Ar) { // Retrieve the state object and the client socket from the asynchronous state object StateToken state = (StateToken)Ar.AsyncState; Socket clt = state.Client; try { // Read data from the remote device. int bytesRead = clt.EndReceive(Ar); if (bytesRead > MaxAllocation) throw new CryptoSocketException("TcpSocket:ReceiveCallback", string.Format("The Tcp stream is larger than the maximum allocation size of {0} bytes!", MaxAllocation), new InvalidOperationException()); if (bytesRead > 0) { // there might be more data, so store the data received so far state.Data.Write(state.Buffer, 0, bytesRead); // all the data has arrived; put it in response. if (state.Data.Length > 1) { // return the data if (DataReceived != null) { state.Data.Seek(0, SeekOrigin.Begin); DataReceivedEventArgs args = new DataReceivedEventArgs(state, 0); DataReceived(args); } } if (state.Client.Connected) { // clear the state state.Data = new MemoryStream(); // get more data clt.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, new AsyncCallback(ReceiveCallback), state); } } } catch (SocketException se) { // expected when remote connection goes down if (se.ErrorCode != (int)SocketError.ConnectionReset && se.ErrorCode != (int)SocketError.Disconnecting) throw new CryptoSocketException("TcpSocket:ReceiveCallback", "The Tcp receiver has failed!", se); } catch (ObjectDisposedException) { // disconnected if (DisConnected != null) DisConnected(this, SocketError.NotConnected); } catch (NullReferenceException) { // expected when shutting down } catch { throw; } }