// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.IO; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; namespace EpicGames.Core { /// /// Extension methods for sockets /// public static class SocketExtensions { /// /// Reads a complete buffer from the given socket, retrying reads until the buffer is full. /// /// Socket to read from /// Buffer to store the data /// Flags for the socket receive call /// Cancellation token for the operation public static async Task ReceiveMessageAsync(this Socket socket, Memory buffer, SocketFlags socketFlags, CancellationToken cancellationToken) { if (!await TryReceiveMessageAsync(socket, buffer, socketFlags, cancellationToken)) { throw new EndOfStreamException(); } } /// /// Reads a complete buffer from the given socket, retrying reads until the buffer is full. /// /// Socket to read from /// Buffer to store the data /// Flags for the socket receive call /// Cancellation token for the operation public static async Task TryReceiveMessageAsync(this Socket socket, Memory buffer, SocketFlags socketFlags, CancellationToken cancellationToken) { for (int offset = 0; offset < buffer.Length;) { int read = await socket.ReceiveAsync(buffer.Slice(offset), socketFlags, cancellationToken); if (read == 0) { return false; } offset += read; } return true; } /// /// Sends a complete buffer over the given socket. /// /// Socket to write to /// Buffer to write /// Flags for the socket sent call /// Cancellation token for the operation /// public static async Task SendMessageAsync(this Socket socket, ReadOnlyMemory buffer, SocketFlags socketFlags, CancellationToken cancellationToken) { while (buffer.Length > 0) { int written = await socket.SendAsync(buffer, socketFlags, cancellationToken); buffer = buffer.Slice(written); } } } }