/// <summary> /// Called when the <see cref="PacketReceived"/> event is raised. /// </summary> /// <remarks> /// When overriding this method in a derived class, call the base implementation after your logic. /// </remarks> /// <param name="sender">The sender of the event.</param> /// <param name="args">The packet data that was received.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="args"/> is <see langword="null"/>.</exception> protected virtual void OnDataArrived(object sender, DataArrivedEventArgs args) { Guard.NotNull(() => args, args); byte[] data = args.Data; int position = 0, remaining = data.Length; while (PacketBuffer.FreeSpace == 0) { byte[] rawData = PacketBuffer.ExtractAndReset(0); if (rawData.Length > 0) { Crypto.Decrypt(rawData); var incomingPacketArgs = new PacketReceivedEventArgs(rawData); OnPacketReceived(incomingPacketArgs); } if (remaining == 0) { break; } int bufferred; int headerRemaining = HeaderBuffer.FreeSpace; if (headerRemaining > 0) { bufferred = HeaderBuffer.AppendFill(data, position, headerRemaining); // For the confused: if we didn't fill the header, it // means the data array didn't have enough elements. // We move on. if (bufferred < headerRemaining) { break; } position += bufferred; remaining -= bufferred; } byte[] header = HeaderBuffer.ExtractAndReset(4); int length; if (!Crypto.TryGetLength(header, out length)) { Close(@"Could not decode packet length."); return; } PacketBuffer.Reset(length); bufferred = PacketBuffer.AppendFill(data, position, remaining); position += bufferred; remaining -= bufferred; } }
/// <summary> /// Handles the transferred data for the operation. /// </summary> /// <remarks> /// This method returns <see langword="false"/> on connection errors. /// </remarks> /// <param name="args">The <see cref="SocketAsyncEventArgs"/> object for this operation.</param> /// <returns><see langword="true"/> if there is more data to send; otherwise, <see langword="false"/>.</returns> private bool HandleTransferredData(SocketAsyncEventArgs args) { int transferred = args.BytesTransferred; if (transferred <= 0) { OnError(args); return(false); } var dataCopy = new byte[transferred]; Buffer.BlockCopy(args.Buffer, 0, dataCopy, 0, transferred); var eventArgs = new DataArrivedEventArgs(dataCopy); DataArrivedInternal.Invoke(this, eventArgs); return(true); }
/// <summary> /// Called when the <see cref="PacketReceived"/> event is raised. /// </summary> /// <remarks> /// When overriding this method in a derived class, call the base implementation after your logic. /// </remarks> /// <param name="sender">The sender of the event.</param> /// <param name="args">The packet data that was received.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="args"/> is <see langword="null"/>.</exception> protected virtual void OnDataArrived(object sender, DataArrivedEventArgs args) { Guard.NotNull(() => args, args); byte[] data = args.Data; int position = 0, remaining = data.Length; while (this.PacketBuffer.FreeSpace == 0) { byte[] rawData = this.PacketBuffer.ExtractAndReset(0); if (rawData.Length > 0) { this.Crypto.Decrypt(rawData); var incomingPacketArgs = new PacketReceivedEventArgs(rawData); this.OnPacketReceived(incomingPacketArgs); } if (remaining == 0) { break; } int bufferred; int headerRemaining = this.HeaderBuffer.FreeSpace; if (headerRemaining > 0) { bufferred = this.HeaderBuffer.AppendFill(data, position, headerRemaining); // For the confused: if we didn't fill the header, it // means the data array didn't have enough elements. // We move on. if (bufferred < headerRemaining) { break; } position += bufferred; remaining -= bufferred; } byte[] header = this.HeaderBuffer.ExtractAndReset(4); int length; if (!this.Crypto.TryGetLength(header, out length)) { this.Close(@"Could not decode packet length."); return; } this.PacketBuffer.Reset(length); bufferred = this.PacketBuffer.AppendFill(data, position, remaining); position += bufferred; remaining -= bufferred; } }
/// <summary> /// Handles the transferred data for the operation. /// </summary> /// <remarks> /// This method returns <see langword="false"/> on connection errors. /// </remarks> /// <param name="args">The <see cref="SocketAsyncEventArgs"/> object for this operation.</param> /// <returns><see langword="true"/> if there is more data to send; otherwise, <see langword="false"/>.</returns> private bool HandleTransferredData(SocketAsyncEventArgs args) { int transferred = args.BytesTransferred; if (transferred <= 0) { this.OnError(args); return false; } var dataCopy = new byte[transferred]; Buffer.BlockCopy(args.Buffer, 0, dataCopy, 0, transferred); var eventArgs = new DataArrivedEventArgs(dataCopy); this.DataArrivedInternal.Invoke(this, eventArgs); return true; }