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