commit 97cf9b9f20d1a0ee9781222d9a07bb645400fb39
parent d652bdc062aefec5267d47284a4db0b651c36fc9
Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com>
Date: Fri, 10 Apr 2020 15:17:21 +0100
Improved on DatagramSocketClient, implementing synchronous and asynchronous methods.
Diffstat:
65 files changed, 417 insertions(+), 8757 deletions(-)
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/ConnectPacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/ConnectPacket.cs
@@ -1,32 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A simple connection request packet for the UDP protocol.
- /// </summary>
- [PacketTypeId(1)]
- internal class ConnectPacket : IRequestPacket
- {
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return Memory<byte>.Empty;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/ConnectResponsePacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/ConnectResponsePacket.cs
@@ -1,35 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A response packet for the <see cref="ConnectPacket"/>.
- /// </summary>
- [PacketTypeId(2)]
- internal class ConnectResponsePacket : IResponsePacket<ConnectPacket>
- {
- /// <inheritdoc />
- public ConnectPacket RequestPacket { get; set; } = new ConnectPacket();
-
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return Memory<byte>.Empty;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/DataPacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/DataPacket.cs
@@ -1,55 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A simple data transfer packet, that allows for the transmission of an arbitrary number of frames.
- /// </summary>
- [PacketTypeId(5)]
- public class DataPacket : IRequestPacket
- {
- /// <summary>
- /// The data that should be transferred across the network.
- /// </summary>
- public Memory<byte> RequestBuffer;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="DataPacket"/> class.
- /// </summary>
- public DataPacket()
- {
- RequestBuffer = new byte[0];
- }
-
- /// <summary>
- /// Initialises a new instance of the <see cref="DataPacket"/> class.
- /// </summary>
- /// <param name="buffer">The data that this request packet should contain.</param>
- public DataPacket(Memory<byte> buffer)
- {
- RequestBuffer = buffer;
- }
-
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- RequestBuffer = serialisedObject.ToArray();
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return RequestBuffer;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/DataResponsePacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/DataResponsePacket.cs
@@ -1,58 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A response packet for the <see cref="DataPacket"/>.
- /// </summary>
- [PacketTypeId(6)]
- public class DataResponsePacket : IResponsePacket<DataPacket>
- {
- /// <summary>
- /// The data that should be transferred across the network.
- /// </summary>
- public Memory<byte> ResponseBuffer;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="DataResponsePacket"/> class.
- /// </summary>
- public DataResponsePacket()
- {
- ResponseBuffer = new byte[0];
- }
-
- /// <summary>
- /// Initialises a new instance of the <see cref="DataResponsePacket"/> class.
- /// </summary>
- /// <param name="buffer">The data that this response packet should contain.</param>
- public DataResponsePacket(Memory<byte> buffer)
- {
- ResponseBuffer = buffer;
- }
-
- /// <inheritdoc />
- public DataPacket RequestPacket { get; internal set; } = new DataPacket();
-
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- ResponseBuffer = serialisedObject.ToArray();
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return ResponseBuffer;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/DisconnectPacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/DisconnectPacket.cs
@@ -1,32 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A simple disconnect packet for the UDP protocol.
- /// </summary>
- [PacketTypeId(0)]
- internal class DisconnectPacket : IRequestPacket
- {
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return Memory<byte>.Empty;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/PingPacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/PingPacket.cs
@@ -1,32 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A simple ping request packet for heartbeat monitoring and RTT measurement.
- /// </summary>
- [PacketTypeId(3)]
- public class PingPacket : IRequestPacket
- {
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return Memory<byte>.Empty;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/PingResponsePacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/PingResponsePacket.cs
@@ -1,35 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A response packet for the <see cref="PingPacket"/>.
- /// </summary>
- [PacketTypeId(4)]
- public class PingResponsePacket : IResponsePacket<PingPacket>
- {
- /// <inheritdoc />
- public PingPacket RequestPacket { get; internal set; } = new PingPacket();
-
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return Memory<byte>.Empty;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Builtin/SimpleDataPacket.cs b/NetSharp/NetSharp/Deprecated/Builtin/SimpleDataPacket.cs
@@ -1,55 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated.Builtin
-{
- /// <summary>
- /// A simple one-time-use data transfer packet, that allows for the transmission of an arbitrary number of frames.
- /// </summary>
- [PacketTypeId(7)]
- public class SimpleDataPacket : IRequestPacket
- {
- /// <summary>
- /// The data that should be transferred across the network.
- /// </summary>
- public Memory<byte> RequestBuffer;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="SimpleDataPacket"/> class.
- /// </summary>
- public SimpleDataPacket()
- {
- RequestBuffer = new byte[0];
- }
-
- /// <summary>
- /// Initialises a new instance of the <see cref="SimpleDataPacket"/> class.
- /// </summary>
- /// <param name="buffer">The data that this request packet should contain.</param>
- public SimpleDataPacket(Memory<byte> buffer)
- {
- RequestBuffer = buffer;
- }
-
- /// <inheritdoc />
- public void AfterDeserialisation()
- {
- }
-
- /// <inheritdoc />
- public void BeforeSerialisation()
- {
- }
-
- /// <inheritdoc />
- public void Deserialise(ReadOnlyMemory<byte> serialisedObject)
- {
- RequestBuffer = serialisedObject.ToArray();
- }
-
- /// <inheritdoc />
- public Memory<byte> Serialise()
- {
- return RequestBuffer;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Client.cs b/NetSharp/NetSharp/Deprecated/Client.cs
@@ -1,191 +0,0 @@
-using NetSharp.Deprecated.Builtin;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides methods for connecting to and talking with a <see cref="IServer"/> instance.
- /// </summary>
- public abstract class Client : ServerClientConnection, IClient, IDisposable
- {
- /// <summary>
- /// Initialises a new instance of the <see cref="Client"/> class.
- /// </summary>
- private Client()
- {
- remoteEndPoint = new IPEndPoint(IPAddress.None, IPEndPoint.MinPort);
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-
- socketOptions = new DefaultSocketOptions(ref socket);
- }
-
- /// <summary>
- /// Destroys an instance of the <see cref="Client"/> class.
- /// </summary>
- ~Client()
- {
- Dispose(false);
- }
-
- /// <summary>
- /// The <see cref="Socket"/> underlying the connection.
- /// </summary>
- protected readonly Socket socket;
-
- /// <summary>
- /// Backing field for the <see cref="SocketOptions"/> property.
- /// </summary>
- protected readonly SocketOptions socketOptions;
-
- /// <summary>
- /// The remote endpoint with which this client communicates.
- /// </summary>
- protected EndPoint remoteEndPoint;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="Client"/> class.
- /// </summary>
- /// <param name="socketType">The socket type for the underlying socket.</param>
- /// <param name="protocolType">The protocol type for the underlying socket.</param>
- /// <param name="socketManager">The <see cref="Utils.Socket_Options.SocketOptions"/> manager to use.</param>
- protected Client(SocketType socketType, ProtocolType protocolType) : this()
- {
- socket = new Socket(AddressFamily.InterNetwork, socketType, protocolType);
- }
-
- /// <summary>
- /// Disposes of this <see cref="Client"/> instance.
- /// </summary>
- /// <param name="disposing">Whether this instance is being disposed.</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- socket.Dispose();
- }
-
- base.Dispose(disposing);
- }
-
- /// <summary>
- /// Invokes the <see cref="Connected"/> event.
- /// </summary>
- /// <param name="endPoint">The remote endpoint with which a connection was made.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnConnected(EndPoint endPoint) => Connected?.Invoke(endPoint);
-
- /// <summary>
- /// Invokes the <see cref="Disconnected"/> event.
- /// </summary>
- /// <param name="endPoint">The remote endpoint with which a connection was lost.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnDisconnected(EndPoint endPoint) => Disconnected?.Invoke(endPoint);
-
- /// <inheritdoc />
- public event Action<EndPoint>? Connected;
-
- /// <inheritdoc />
- public event Action<EndPoint>? Disconnected;
-
- /// <summary>
- /// The configured socket options for the underlying connection.
- /// </summary>
- public SocketOptions SocketOptions
- {
- get { return socketOptions; }
- }
-
- /// <summary>
- /// Disconnects the client from the remote endpoint.
- /// </summary>
- public void Disconnect()
- {
- SendSimpleAsync(new DisconnectPacket(), Timeout.InfiniteTimeSpan).Wait();
-
- socket.Shutdown(SocketShutdown.Both);
-
- if (socketOptions is TcpSocketOptions)
- {
- socket.Disconnect(true);
- }
-
- socket.Close();
- }
-
- /// <inheritdoc />
- public abstract Task<bool> SendBytesAsync(byte[] buffer, TimeSpan timeout);
-
- /// <inheritdoc />
- public abstract Task<byte[]> SendBytesWithResponseAsync(byte[] buffer, TimeSpan timeout);
-
- /// <inheritdoc />
- public abstract Task<Rep> SendComplexAsync<Req, Rep>(Req request, TimeSpan timeout)
- where Req : IRequestPacket, new() where Rep : IResponsePacket<Req>, new();
-
- /// <inheritdoc />
- public abstract Task<bool> SendSimpleAsync<Req>(Req request, TimeSpan timeout) where Req : IRequestPacket, new();
-
- /// <inheritdoc />
- public Task<bool> TryBindAsync(IPAddress? localAddress, int? localPort, TimeSpan timeout)
- {
- using CancellationTokenSource cts = new CancellationTokenSource(timeout);
- EndPoint localEndPoint = new IPEndPoint(localAddress ?? IPAddress.Any, localPort ?? 0);
-
- try
- {
- return Task.Run(() =>
- {
- socket.Bind(localEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return Task.FromResult(false);
- }
- catch (SocketException ex)
- {
- logger.LogException($"Socket exception on binding socket to {localEndPoint}:", ex);
- return Task.FromResult(false);
- }
- }
-
- /// <inheritdoc />
- public async Task<bool> TryConnectAsync(IPAddress remoteAddress, int remotePort, TimeSpan timeout)
- {
- using CancellationTokenSource cts = new CancellationTokenSource(timeout);
- remoteEndPoint = new IPEndPoint(remoteAddress, remotePort);
-
- try
- {
- return await Task.Run(async () =>
- {
- await socket.ConnectAsync(remoteEndPoint);
-
- ConnectResponsePacket connectionResponsePacket =
- await SendComplexAsync<ConnectPacket, ConnectResponsePacket>(new ConnectPacket(), timeout);
-
- OnConnected(remoteEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return false;
- }
- catch (SocketException ex)
- {
- logger.LogException($"Socket exception on connection to {remoteEndPoint}:", ex);
- return false;
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ClientExtensions.cs b/NetSharp/NetSharp/Deprecated/ClientExtensions.cs
@@ -1,208 +0,0 @@
-using System;
-using System.Net;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides additional methods and functionality to the <see cref="Client"/> class.
- /// </summary>
- public static class ClientExtensions
- {
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint. Blocks until the bytes are all sent, and does
- /// not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- public static bool SendBytes(this Client instance, byte[] buffer) =>
- instance.SendBytesAsync(buffer, Timeout.InfiniteTimeSpan).Result;
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint. Blocks until the bytes are all sent, whilst
- /// observing a timeout of the given length.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- /// <param name="timeout">The timeout after which to cancel the transmission attempt.</param>
- public static bool SendBytes(this Client instance, byte[] buffer, TimeSpan timeout) =>
- instance.SendBytesAsync(buffer, timeout).Result;
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint asynchronously. Does not block, and does not
- /// timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- public static async Task<bool> SendBytesAsync(this Client instance, byte[] buffer) =>
- await instance.SendBytesAsync(buffer, Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint and waits for the response. Blocks until the
- /// bytes are all sent and the response has been received, and does not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- /// <returns>The byte buffer that was received as a response.</returns>
- public static byte[] SendBytesWithResponse(this Client instance, byte[] buffer) =>
- instance.SendBytesWithResponseAsync(buffer, Timeout.InfiniteTimeSpan).Result;
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint and waits for the response. Blocks until the
- /// bytes are all sent and the response has been received, whilst observing a timeout of the given length.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- /// <param name="timeout">The timeout after which to cancel the transmission attempt.</param>
- /// <returns>The byte buffer that was received as a response.</returns>
- public static byte[] SendBytesWithResponse(this Client instance, byte[] buffer, TimeSpan timeout) =>
- instance.SendBytesWithResponseAsync(buffer, timeout).Result;
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint and waits for the response asynchronously.
- /// Does not block, and does not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- /// <returns>The byte buffer received as a response to the sent buffer.</returns>
- public static async Task<byte[]> SendBytesWithResponseAsync(this Client instance, byte[] buffer) =>
- await instance.SendBytesWithResponseAsync(buffer, Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Sends the given request and listens for a response of the given type. Blocks until the response is received.
- /// Does not timeout.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <typeparam name="Rep">The type of response packet to receive.</typeparam>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="request">The request packet to send.</param>
- /// <returns>The received instance.</returns>
- public static Rep SendComplex<Req, Rep>(this Client instance, Req request)
- where Req : IRequestPacket, new() where Rep : IResponsePacket<Req>, new() =>
- instance.SendComplexAsync<Req, Rep>(request, Timeout.InfiniteTimeSpan).Result;
-
- /// <summary>
- /// Sends the given request and listens for a response of the given type. Blocks until the response is received.
- /// Cancels the operation if the given timeout is exceeded.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <typeparam name="Rep">The type of response packet to receive.</typeparam>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="request">The request packet to send.</param>
- /// <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- /// <returns>The received instance.</returns>
- public static Rep SendComplex<Req, Rep>(this Client instance, Req request, TimeSpan timeout)
- where Req : IRequestPacket, new() where Rep : IResponsePacket<Req>, new() =>
- instance.SendComplexAsync<Req, Rep>(request, timeout).Result;
-
- /// <summary>
- /// Sends the given request and listens for a response of the given type asynchronously. Does not block. Does not timeout.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <typeparam name="Rep">The type of response packet to receive.</typeparam>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="request">The request packet to send.</param>
- /// <returns>The received instance.</returns>
- public static async Task<Rep> SendComplexAsync<Req, Rep>(this Client instance, Req request)
- where Req : IRequestPacket, new() where Rep : IResponsePacket<Req>, new() =>
- await instance.SendComplexAsync<Req, Rep>(request, Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Sends the given request without listening for a response, blocking until it is sent. Does not timeout.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="request">The request packet to send.</param>
- public static bool SendSimple<Req>(this Client instance, Req request) where Req : IRequestPacket, new() =>
- instance.SendSimpleAsync(request, Timeout.InfiniteTimeSpan).Result;
-
- /// <summary>
- /// Sends the given request without listening for a response, blocking until it is sent.
- /// Cancels the operation if the given timeout is exceeded.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="request">The request packet to send.</param>
- /// <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- public static bool SendSimple<Req>(this Client instance, Req request, TimeSpan timeout) where Req : IRequestPacket, new() =>
- instance.SendSimpleAsync(request, timeout).Result;
-
- /// <summary>
- /// Sends the given request asynchronously without listening for a response, not blocking until it is sent.
- /// Does not timeout.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="request">The request packet to send.</param>
- public static async Task<bool> SendSimpleAsync<Req>(this Client instance, Req request) where Req : IRequestPacket, new() =>
- await instance.SendSimpleAsync(request, Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Attempts to synchronously bind the underlying socket to the given local address and port. Blocks. Does not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- /// <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- public static bool TryBind(this Client instance, IPAddress? localAddress, int? localPort)
- => instance.TryBindAsync(localAddress, localPort, Timeout.InfiniteTimeSpan).Result;
-
- /// <summary>
- /// Attempts to synchronously bind the underlying socket to the given local address and port. Blocks.
- /// If the timeout is exceeded the binding attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- /// <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- /// <param name="timeout">The timeout within which to attempt the binding.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- public static bool TryBind(this Client instance, IPAddress? localAddress, int? localPort, TimeSpan timeout)
- => instance.TryBindAsync(localAddress, localPort, timeout).Result;
-
- /// <summary>
- /// Attempts to asynchronously bind the underlying socket to the given local address and port. Does not block.
- /// Does not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- /// <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- public static async Task<bool> TryBindAsync(this Client instance, IPAddress? localAddress, int? localPort)
- => await instance.TryBindAsync(localAddress, localPort, Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Attempts to connect to the remote <see cref="Server"/> at the given <see cref="IPAddress"/> and over the
- /// given port. Does not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="remoteAddress">The remote IP address to connect to.</param>
- /// <param name="remotePort">The remote port to connect over.</param>
- /// <returns>Whether the connection was successful or not.</returns>
- public static bool TryConnect(this Client instance, IPAddress remoteAddress, int remotePort) =>
- instance.TryConnectAsync(remoteAddress, remotePort).Wait(Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Attempts to connect to the remote <see cref="Server"/> at the given <see cref="IPAddress"/> and over the
- /// given port. If the timeout is exceeded the connection attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="remoteAddress">The remote IP address to connect to.</param>
- /// <param name="remotePort">The remote port to connect over.</param>
- /// <param name="timeout">The timeout within which to attempt the connection.</param>
- /// <returns>Whether the connection was successful or not.</returns>
- public static bool TryConnect(this Client instance, IPAddress remoteAddress, int remotePort, TimeSpan timeout) =>
- instance.TryConnectAsync(remoteAddress, remotePort).Wait(timeout);
-
- /// <summary>
- /// Attempts to connect asynchronously to the remote <see cref="Server"/> at the given <see cref="IPAddress"/>
- /// and over the given port. Does not timeout.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="remoteAddress">The remote IP address to connect to.</param>
- /// <param name="remotePort">The remote port to connect over.</param>
- /// <returns>Whether the connection was successful or not.</returns>
- public static async Task<bool> TryConnectAsync(this Client instance, IPAddress remoteAddress, int remotePort) =>
- await instance.TryConnectAsync(remoteAddress, remotePort, Timeout.InfiniteTimeSpan);
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Connection.cs b/NetSharp/NetSharp/Deprecated/Connection.cs
@@ -1,353 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using NetSharp.Utils;
-
-using System;
-using System.Buffers;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Channels;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Encapsulates a connection capable of receiving packets and responding to them with registered packet handlers.
- /// </summary>
- public sealed partial class Connection : IDisposable
- {
- private readonly HashSet<EndPoint> datagramConnections;
- private readonly Channel<(EndPoint origin, Memory<byte> packet)> incomingPacketChannel;
-
- /// <summary>
- /// Pipeline to convert incoming byte buffers to <see cref="NetworkPacket"/> instances.
- /// </summary>
- private readonly PacketPipeline<Memory<byte>, Memory<byte>, NetworkPacket> incomingPacketPipeline;
-
- /// <summary>
- /// Lock synchronisation object for the <see cref="logger"/> variable.
- /// </summary>
- private readonly object loggerLockObject = new object();
-
- private readonly Channel<(EndPoint destination, NetworkPacket packet)> outgoingPacketChannel;
-
- /// <summary>
- /// Pipeline to convert outgoing <see cref="NetworkPacket"/> instances to a byte buffer for sending.
- /// </summary>
- private readonly PacketPipeline<NetworkPacket, Memory<byte>, Memory<byte>> outgoingPacketPipeline;
-
- private readonly Channel<(EndPoint origin, IRequestPacket request)> requestChannel;
-
- /// <summary>
- /// Cancellation token which allows observing the shutdown of the server. It is set when <see cref="ShutdownServer"/> is called.
- /// </summary>
- private readonly CancellationToken ServerShutdownToken;
-
- private readonly ConcurrentDictionary<EndPoint, Socket> streamConnections;
-
- /// <summary>
- /// A logger object allowing for writing debug messages to an output stream.
- /// </summary>
- private Logger logger;
-
- /// <summary>
- /// Destroys a <see cref="Connection"/> class instance, freeing all managed resources.
- /// </summary>
- ~Connection()
- {
- Dispose(false);
- }
-
- private async Task AcceptorWork(object shutdownToken)
- {
- CancellationToken cancellationToken = (CancellationToken)shutdownToken;
-
- logger.LogMessage("Started stream acceptor task.");
-
- async Task StreamListenerWork(object clientArgsObj)
- {
- Socket clientSocket = (Socket)clientArgsObj;
- EndPoint clientEndPoint = clientSocket.RemoteEndPoint;
-
- logger.LogMessage($"Client handler started for {clientEndPoint}");
-
- while (!cancellationToken.IsCancellationRequested)
- {
- // TODO: implement receive buffer pooling
- byte[] receiveBuffer = new byte[NetworkPacket.PacketSize];
- Memory<byte> receiveBufferMemory = new Memory<byte>(receiveBuffer);
-
- TransmissionResult result =
- await DoReceiveFromAsync(clientSocket, clientEndPoint, SocketFlags.None, receiveBufferMemory, cancellationToken);
-
- if (result.Count == 0)
- {
- break;
- }
-
- await incomingPacketChannel.Writer.WriteAsync((result.RemoteEndPoint, receiveBufferMemory),
- cancellationToken);
- }
-
- logger.LogMessage($"Client handler stopped for {clientEndPoint}");
-
- await DoDisconnectAsync(clientSocket, cancellationToken);
-
- clientSocket.Shutdown(SocketShutdown.Both);
- clientSocket.Close(1);
- }
-
- streamSocket.Listen(MaximumConnectionBacklog);
-
- while (!cancellationToken.IsCancellationRequested)
- {
- Socket clientSocket = await DoAcceptAsync(streamSocket, cancellationToken);
-
- if (!streamConnections.ContainsKey(clientSocket.RemoteEndPoint))
- {
- streamConnections[clientSocket.RemoteEndPoint] = clientSocket;
-
- await Task.Factory.StartNew(StreamListenerWork, streamConnections[clientSocket.RemoteEndPoint], ServerShutdownToken);
- }
- else
- {
- logger.LogWarning($"Accepted duplicate connection from {clientSocket.RemoteEndPoint}");
- }
- }
-
- logger.LogMessage("Stopped stream acceptor task.");
- }
-
- private async Task DatagramListenerWork(object shutdownToken)
- {
- CancellationToken cancellationToken = (CancellationToken)shutdownToken;
-
- logger.LogMessage("Started datagram listener task.");
-
- while (!cancellationToken.IsCancellationRequested)
- {
- // TODO: implement receive buffer pooling
- byte[] receiveBuffer = new byte[NetworkPacket.PacketSize];
- Memory<byte> receiveBufferMemory = new Memory<byte>(receiveBuffer);
-
- TransmissionResult result =
- await DoReceiveFromAsync(datagramSocket, AnyRemoteEndPoint, SocketFlags.None,
- receiveBufferMemory, cancellationToken);
-
- if (!datagramConnections.Contains(result.RemoteEndPoint))
- {
- datagramConnections.Add(result.RemoteEndPoint);
- }
-
- await incomingPacketChannel.Writer.WriteAsync((result.RemoteEndPoint, receiveBufferMemory), cancellationToken);
- }
-
- logger.LogMessage("Stopped datagram listener task.");
- }
-
- private async Task IncomingPacketHandlerWork(object shutdownToken)
- {
- CancellationToken cancellationToken = (CancellationToken)shutdownToken;
-
- logger.LogMessage("Started incoming packet handler task.");
-
- while (!cancellationToken.IsCancellationRequested)
- {
- (EndPoint origin, Memory<byte> packet) =
- await incomingPacketChannel.Reader.ReadAsync(cancellationToken);
-
- NetworkPacket deserialisedRequest = incomingPacketPipeline.ProcessPacket(packet);
-
- // TODO implement deserialisation according to registered packet deserialisers
-
- // TODO: write to requestChannel, not to outgoingPacketChannel
- await outgoingPacketChannel.Writer.WriteAsync((origin, deserialisedRequest), cancellationToken);
- }
-
- logger.LogMessage("Stopped incoming packet handler task.");
- }
-
- private async Task OutgoingPacketHandlerWork(object shutdownToken)
- {
- CancellationToken cancellationToken = (CancellationToken)shutdownToken;
-
- logger.LogMessage("Started outgoing packet handler task.");
-
- while (!cancellationToken.IsCancellationRequested)
- {
- (EndPoint destination, NetworkPacket packet) =
- await outgoingPacketChannel.Reader.ReadAsync(cancellationToken);
-
- Memory<byte> serialisedResponse = outgoingPacketPipeline.ProcessPacket(packet);
-
- if (streamConnections.ContainsKey(destination))
- {
- Socket streamConnection = streamConnections[destination];
-
- await DoSendToAsync(streamConnection, destination, SocketFlags.None,
- serialisedResponse, cancellationToken);
- }
- else if (datagramConnections.Contains(destination))
- {
- await DoSendToAsync(datagramSocket, destination, SocketFlags.None,
- serialisedResponse, cancellationToken);
- }
- else
- {
- logger.LogWarning($"Packet destined for unknown destination: {destination}");
- }
- }
-
- logger.LogMessage("Stopped outgoing packet handler task.");
- }
-
- private async Task RequestHandlerInvocationWork(object shutdownToken)
- {
- CancellationToken cancellationToken = (CancellationToken)shutdownToken;
-
- logger.LogMessage("Started request handler invocation task.");
-
- while (!cancellationToken.IsCancellationRequested)
- {
- (EndPoint origin, IRequestPacket request) = await requestChannel.Reader.ReadAsync(cancellationToken);
-
- // TODO: implement proper request handling, and conversion to IResponsePacket<IRequestPacke>
-
- NetworkPacket serialisedResponsePacket = new NetworkPacket();
-
- await outgoingPacketChannel.Writer.WriteAsync((origin, serialisedResponsePacket), cancellationToken);
- }
-
- logger.LogMessage("Stopped request handler invocation task.");
- }
-
- internal Connection(
- PacketPipeline<Memory<byte>, Memory<byte>, NetworkPacket> incomingPacketPipeline,
- PacketPipeline<NetworkPacket, Memory<byte>, Memory<byte>> outgoingPacketPipeline,
- int objectPoolSize = 10, bool preallocateBuffers = false, Stream? loggingStream = default,
- LogLevel minimumLoggedSeverity = LogLevel.Info)
- {
- serverShutdownTokenSource = new CancellationTokenSource();
- ServerShutdownToken = serverShutdownTokenSource.Token;
-
- streamSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- datagramSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
-
- sendToBufferPool = ArrayPool<byte>.Create(NetworkPacket.PacketSize, objectPoolSize);
- receiveFromBufferPool = ArrayPool<byte>.Create(NetworkPacket.PacketSize, objectPoolSize);
-
- clientSocketArgsPool =
- new LeakTrackingObjectPool<SocketAsyncEventArgs>(
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- objectPoolSize));
- receiveArgsPool =
- new LeakTrackingObjectPool<SocketAsyncEventArgs>(
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- objectPoolSize));
- sendArgsPool =
- new LeakTrackingObjectPool<SocketAsyncEventArgs>(
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- objectPoolSize));
-
- for (int i = 0; i < objectPoolSize; i++)
- {
- SocketAsyncEventArgs clientArgs = new SocketAsyncEventArgs();
- clientArgs.Completed += HandleIOCompleted;
- clientSocketArgsPool.Return(clientArgs);
-
- SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
- receiveArgs.Completed += HandleIOCompleted;
- receiveArgsPool.Return(receiveArgs);
-
- SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs();
- sendArgs.Completed += HandleIOCompleted;
- sendArgsPool.Return(sendArgs);
- }
-
- if (preallocateBuffers)
- {
- //TODO: Preallocate buffers someday
- }
-
- streamConnections = new ConcurrentDictionary<EndPoint, Socket>();
- datagramConnections = new HashSet<EndPoint>();
-
- this.incomingPacketPipeline = incomingPacketPipeline;
- BoundedChannelOptions incomingChannelOptions = new BoundedChannelOptions(MaximumPacketBacklog)
- {
- FullMode = BoundedChannelFullMode.DropOldest,
- SingleReader = true,
- SingleWriter = false,
- };
- incomingPacketChannel = Channel.CreateBounded<(EndPoint origin, Memory<byte> packet)>(incomingChannelOptions);
-
- BoundedChannelOptions requestChannelOptions = new BoundedChannelOptions(MaximumPacketBacklog)
- {
- FullMode = BoundedChannelFullMode.DropOldest,
- SingleReader = true,
- SingleWriter = true,
- };
- requestChannel = Channel.CreateBounded<(EndPoint origin, IRequestPacket request)>(requestChannelOptions);
-
- this.outgoingPacketPipeline = outgoingPacketPipeline;
- BoundedChannelOptions outgoingChannelOptions = new BoundedChannelOptions(MaximumPacketBacklog)
- {
- FullMode = BoundedChannelFullMode.DropOldest,
- SingleReader = true,
- SingleWriter = true,
- };
- outgoingPacketChannel = Channel.CreateBounded<(EndPoint destination, NetworkPacket packet)>(outgoingChannelOptions);
-
- logger = new Logger(loggingStream ?? Stream.Null, minimumLoggedSeverity);
- }
-
- /// <summary>
- /// Makes the connection listen for incoming request packets, and handle them according to registered packet handler delegates.
- /// This work can be cancelled by calling <see cref="ShutdownServer"/>.
- /// </summary>
- /// <returns>The task representing the connection work.</returns>
- public Task RunServerAsync()
- {
- logger.LogMessage("Starting stream acceptor task...");
- Task acceptorThread =
- Task.Factory.StartNew(AcceptorWork, ServerShutdownToken, ServerShutdownToken, TaskCreationOptions.LongRunning,
- TaskScheduler.Default).Result;
-
- logger.LogMessage("Starting datagram listener task...");
- Task datagramListenerThread =
- Task.Factory.StartNew(DatagramListenerWork, ServerShutdownToken, ServerShutdownToken, TaskCreationOptions.LongRunning,
- TaskScheduler.Default);
-
- logger.LogMessage("Starting incoming packet handler task...");
- Task incomingPacketHandlerThread =
- Task.Factory.StartNew(IncomingPacketHandlerWork, ServerShutdownToken, ServerShutdownToken, TaskCreationOptions.LongRunning,
- TaskScheduler.Default);
-
- logger.LogMessage("Starting request packet invocation task...");
- Task requestHandlerInvocationThread =
- Task.Factory.StartNew(RequestHandlerInvocationWork, ServerShutdownToken, ServerShutdownToken, TaskCreationOptions.LongRunning,
- TaskScheduler.Default).Result;
-
- logger.LogMessage("Starting outgoing packet handler task...");
- Task outgoingPacketHandlerThread =
- Task.Factory.StartNew(OutgoingPacketHandlerWork, ServerShutdownToken, ServerShutdownToken, TaskCreationOptions.LongRunning,
- TaskScheduler.Default);
-
- return Task.WhenAll(acceptorThread, datagramListenerThread,
- incomingPacketHandlerThread, requestHandlerInvocationThread, outgoingPacketHandlerThread);
- }
-
- /// <summary>
- /// Shuts down the connection, and releases managed and unmanaged resources.
- /// </summary>
- public void ShutdownServer()
- {
- logger.LogMessage("Signalling shutdown to all client connection handlers...");
- serverShutdownTokenSource.Cancel();
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ConnectionBase.cs b/NetSharp/NetSharp/Deprecated/ConnectionBase.cs
@@ -1,465 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using NetSharp.Utils;
-
-using System;
-using System.Buffers;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Implements low-level network access on top of which the rest of the connection is built upon.
- /// </summary>
- public sealed partial class Connection : IDisposable
- {
- /// <summary>
- /// Represents any remote endpoint for datagram operations.
- /// </summary>
- private static readonly EndPoint AnyRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
-
- private readonly ObjectPool<SocketAsyncEventArgs> clientSocketArgsPool;
-
- private readonly Socket datagramSocket;
-
- private readonly ObjectPool<SocketAsyncEventArgs> receiveArgsPool;
-
- private readonly ArrayPool<byte> receiveFromBufferPool;
-
- private readonly ObjectPool<SocketAsyncEventArgs> sendArgsPool;
-
- private readonly ArrayPool<byte> sendToBufferPool;
-
- private readonly CancellationTokenSource serverShutdownTokenSource;
-
- private readonly Socket streamSocket;
-
- /// <summary>
- /// Disposes of the managed and unmanaged resources held by this instance.
- /// </summary>
- /// <param name="disposing">Whether this method is called by <see cref="Dispose()"/> or by the finaliser.</param>
- private void Dispose(bool disposing)
- {
- if (disposing)
- {
- serverShutdownTokenSource.Cancel();
- serverShutdownTokenSource.Dispose();
-
- streamSocket.Dispose();
- datagramSocket.Dispose();
- }
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket accept operation.
- /// </summary>
- /// <param name="serverSocket">The socket which should be used to accept an incoming connection attempt.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- /// <returns>The accepted socket.</returns>
- private async Task<Socket> DoAcceptAsync(Socket serverSocket, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<Socket> tcs = new TaskCompletionSource<Socket>();
-
- cancellationToken.Register(() => tcs.SetCanceled());
-
- Task<Socket> task = serverSocket.AcceptAsync();
- Task<Socket> completedTask = await Task.WhenAny(task, tcs.Task);
-
- if (completedTask == task)
- {
- Socket result = await task;
-
- tcs.SetResult(result);
- }
-
- return await tcs.Task;
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket connect operation.
- /// </summary>
- /// <param name="socket">The socket which should asynchronously connect to the remote endpoint.</param>
- /// <param name="remoteEndPoint">The remote endpoint to which the socket should connect.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- private async Task DoConnectAsync(Socket socket, EndPoint remoteEndPoint, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-
- cancellationToken.Register(() => tcs.SetCanceled());
-
- Task task = socket.ConnectAsync(remoteEndPoint);
- Task completedTask = await Task.WhenAny(task, tcs.Task);
-
- if (completedTask == task)
- {
- await task;
- tcs.SetResult(true);
- }
-
- await tcs.Task;
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket disconnect operation.
- /// </summary>
- /// <param name="connectedSocket">The socket which should asynchronously disconnect from its remote endpoint.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- private Task DoDisconnectAsync(Socket connectedSocket, CancellationToken cancellationToken = default)
- {
- return Task.Factory.StartNew(() =>
- {
- connectedSocket.Disconnect(true);
- }, cancellationToken);
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket receive operation.
- /// </summary>
- /// <param name="listenerSocket">The socket which should receive data from the remote endpoint.</param>
- /// <param name="remoteEndPoint">The remove endpoint from which data should be received.</param>
- /// <param name="socketFlags">The socket flags associated with the receive operation.</param>
- /// <param name="inputBuffer">The memory buffer into which received data will be stored.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- /// <returns>The result of the receive operation from the remote endpoint.</returns>
- private Task<TransmissionResult> DoReceiveFromAsync(Socket listenerSocket, EndPoint remoteEndPoint, SocketFlags socketFlags,
- Memory<byte> inputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
-
- byte[] rentedReceiveFromBuffer = receiveFromBufferPool.Rent(NetworkPacket.PacketSize);
- Memory<byte> rentedReceiveFromBufferMemory = new Memory<byte>(rentedReceiveFromBuffer);
-
- SocketAsyncEventArgs clientArgs = receiveArgsPool.Get();
- clientArgs.SetBuffer(rentedReceiveFromBufferMemory);
- clientArgs.SocketFlags = socketFlags;
- clientArgs.RemoteEndPoint = remoteEndPoint;
- clientArgs.UserToken = new AsyncReadToken(rentedReceiveFromBuffer, inputBuffer, tcs, cancellationToken);
-
- // if the receive operation doesn't complete synchronously, returns the awaitable task
- if (listenerSocket.ReceiveFromAsync(clientArgs)) return tcs.Task;
-
- clientArgs.MemoryBuffer.CopyTo(inputBuffer);
-
- TransmissionResult result = new TransmissionResult(clientArgs);
-
- receiveFromBufferPool.Return(rentedReceiveFromBuffer, true);
- receiveArgsPool.Return(clientArgs);
-
- return Task.FromResult(result);
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket send operation.
- /// </summary>
- /// <param name="transmitterSocket">The socket which should send the data to the remote endpoint.</param>
- /// <param name="remoteEndPoint">The remote endpoint to which data should be written.</param>
- /// <param name="socketFlags">The socket flags associated with the send operation.</param>
- /// <param name="outputBuffer">The data buffer which should be sent.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- /// <returns>The result of the send operation to the remote endpoint.</returns>
- private ValueTask<int> DoSendToAsync(Socket transmitterSocket, EndPoint remoteEndPoint, SocketFlags socketFlags,
- Memory<byte> outputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
-
- byte[] rentedSendToBuffer = sendToBufferPool.Rent(NetworkPacket.PacketSize);
- Memory<byte> rentedSendToBufferMemory = new Memory<byte>(rentedSendToBuffer);
-
- outputBuffer.CopyTo(rentedSendToBufferMemory);
-
- SocketAsyncEventArgs clientArgs = sendArgsPool.Get();
- clientArgs.SetBuffer(rentedSendToBufferMemory);
- clientArgs.SocketFlags = socketFlags;
- clientArgs.RemoteEndPoint = remoteEndPoint;
- clientArgs.UserToken = new AsyncWriteToken(rentedSendToBuffer, tcs, cancellationToken);
-
- /* NOT WORKING, NEED SOLUTION AT SOME POINT!!!
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- sendBufferPool.Return(rentedSendToBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- sendAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the send operation doesn't complete synchronously, return the awaitable task
- if (transmitterSocket.SendToAsync(clientArgs)) return new ValueTask<int>(tcs.Task);
-
- int result = clientArgs.BytesTransferred;
-
- sendToBufferPool.Return(rentedSendToBuffer, true);
- sendArgsPool.Return(clientArgs);
-
- return new ValueTask<int>(result);
- }
-
- private void HandleIOCompleted(object? sender, SocketAsyncEventArgs args)
- {
- switch (args.LastOperation)
- {
- case SocketAsyncOperation.SendTo:
- AsyncWriteToken asyncSendToToken = (AsyncWriteToken)args.UserToken;
-
- if (asyncSendToToken.CancellationToken.IsCancellationRequested)
- {
- asyncSendToToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncSendToToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncSendToToken.CompletionSource.SetResult(args.BytesTransferred);
- }
- }
-
- sendToBufferPool.Return(asyncSendToToken.RentedBuffer, true);
- sendArgsPool.Return(args);
-
- break;
-
- case SocketAsyncOperation.ReceiveFrom:
- AsyncReadToken asyncReceiveFromToken = (AsyncReadToken)args.UserToken;
-
- if (asyncReceiveFromToken.CancellationToken.IsCancellationRequested)
- {
- asyncReceiveFromToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncReceiveFromToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else if (args.BytesTransferred <= 0)
- {
- TransmissionResult result = new TransmissionResult(args);
-
- asyncReceiveFromToken.CompletionSource.SetResult(result);
- }
- else
- {
- args.MemoryBuffer.CopyTo(asyncReceiveFromToken.UserBuffer);
-
- TransmissionResult result = new TransmissionResult(args);
-
- asyncReceiveFromToken.CompletionSource.SetResult(result);
- }
- }
-
- receiveFromBufferPool.Return(asyncReceiveFromToken.RentedBuffer, true);
- receiveArgsPool.Return(args);
-
- break;
-
- default:
- throw new InvalidOperationException(
- $"The {nameof(Connection)} class doesn't support the {args.LastOperation} operation.");
- }
- }
-
- private readonly struct AsyncReadToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
- public readonly byte[] RentedBuffer;
- public readonly Memory<byte> UserBuffer;
-
- public AsyncReadToken(byte[] rentedBuffer, Memory<byte> userBuffer, TaskCompletionSource<TransmissionResult> tcs,
- CancellationToken cancellationToken = default)
- {
- RentedBuffer = rentedBuffer;
- UserBuffer = userBuffer;
-
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- private readonly struct AsyncWriteToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<int> CompletionSource;
- public readonly byte[] RentedBuffer;
-
- public AsyncWriteToken(byte[] rentedBuffer, TaskCompletionSource<int> tcs,
- CancellationToken cancellationToken = default)
- {
- RentedBuffer = rentedBuffer;
-
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- /// <summary>
- /// The maximum number of stream connection that will be accepted.
- /// </summary>
- /// TODO change this to a configurable builder option
- public const int MaximumConnectionBacklog = 10;
-
- /// <summary>
- /// The maximum number of packets that will be stored before older packets start to be dropped.
- /// </summary>
- /// TODO change this to a configurable builder option
- public const int MaximumPacketBacklog = 64;
-
- /// <inheritdoc />
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- public Task<TransmissionResult> ReceiveAsync(Memory<byte> inputBuffer, SocketFlags flags, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- return DoReceiveFromAsync(streamSocket, streamSocket.RemoteEndPoint, flags, inputBuffer, cts.Token);
- }
-
- public Task<TransmissionResult> ReceiveFromAsync(EndPoint remoteEndPoint, Memory<byte> inputBuffer, SocketFlags flags, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- return DoReceiveFromAsync(datagramSocket, remoteEndPoint, flags, inputBuffer, cts.Token);
- }
-
- public ValueTask<int> SendAsync(Memory<byte> outputBuffer, SocketFlags flags, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- return DoSendToAsync(streamSocket, streamSocket.RemoteEndPoint, flags, outputBuffer, cts.Token);
- }
-
- public ValueTask<int> SendToAsync(EndPoint remoteEndPoint, Memory<byte> outputBuffer, SocketFlags flags, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- return DoSendToAsync(datagramSocket, remoteEndPoint, flags, outputBuffer, cts.Token);
- }
-
- /// <summary>
- /// Configures the logger to log messages to the given stream (or to <see cref="Stream.Null"/> if <c>null</c>) and
- /// to only log messages that are of severity <paramref name="minimumLoggedSeverity"/> or higher.
- /// </summary>
- /// <param name="loggingStream">The stream to which messages will be logged.</param>
- /// <param name="minimumLoggedSeverity">The minimum severity a message must be to be logged.</param>
- public void SetLoggingStream(Stream? loggingStream, LogLevel minimumLoggedSeverity = LogLevel.Info)
- {
- lock (loggerLockObject)
- {
- logger = new Logger(loggingStream ?? Stream.Null, minimumLoggedSeverity);
- }
- }
-
- /// <summary>
- /// Attempts to asynchronously bind the underlying socket to the given local endpoint. Does not block.
- /// If the timeout is exceeded the binding attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="localEndPoint">The local endpoint to bind to.</param>
- /// <param name="timeout">The timeout within which to attempt the binding.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- public async Task<bool> TryBindAsync(EndPoint localEndPoint, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- try
- {
- return await Task.Run(() =>
- {
- streamSocket.Bind(localEndPoint);
- datagramSocket.Bind(localEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return false;
- }
- catch (SocketException ex)
- {
- logger.LogException($"Socket exception on binding socket to {localEndPoint}:", ex);
- return false;
- }
- }
-
- public async Task<bool> TryConnectAsync(EndPoint remoteEndPoint, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- try
- {
- await DoConnectAsync(streamSocket, remoteEndPoint, cts.Token);
-
- return true;
- }
- catch (TaskCanceledException)
- {
- return false;
- }
- catch (SocketException ex)
- {
- logger.LogException($"Socket exception on connecting socket to {remoteEndPoint}:", ex);
- return false;
- }
- }
-
- public async Task<bool> TryDisconnectAsync(TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, ServerShutdownToken);
-
- try
- {
- await DoDisconnectAsync(streamSocket, cts.Token);
-
- streamSocket.Shutdown(SocketShutdown.Both);
- streamSocket.Close(1);
-
- return true;
- }
- catch (TaskCanceledException)
- {
- return false;
- }
- catch (SocketException ex)
- {
- logger.LogException($"Socket exception on disconnecting socket:", ex);
- return false;
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ConnectionBuilder.cs b/NetSharp/NetSharp/Deprecated/ConnectionBuilder.cs
@@ -1,186 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows for configuring and subsequently building a <see cref="Connection"/> instance.
- /// </summary>
- public sealed class ConnectionBuilder
- {
- private static readonly LoggingSettings DefaultLoggingSettings =
- new LoggingSettings(Stream.Null, LogLevel.Warn);
-
- private static readonly PoolingSettings DefaultPoolingSettings =
- new PoolingSettings(10, false);
-
- private readonly List<Func<Memory<byte>, Memory<byte>>> incomingPipelineStages =
- new List<Func<Memory<byte>, Memory<byte>>>();
-
- private readonly List<Func<Memory<byte>, Memory<byte>>> outgoingPipelineStages =
- new List<Func<Memory<byte>, Memory<byte>>>();
-
- private LoggingSettings? loggingSettings;
- private PoolingSettings? poolingSettings;
-
- /// <summary>
- /// The number of stages in the currently configured incoming packet pipeline.
- /// </summary>
- public int IncomingPacketPipelineStageCount
- {
- get { return incomingPipelineStages.Count; }
- }
-
- /// <summary>
- /// The number of stages in the currently configured outgoing packet pipeline.
- /// </summary>
- public int OutgoingPacketPipelineStageCount
- {
- get { return outgoingPipelineStages.Count; }
- }
-
- /// <summary>
- /// Returns a new <see cref="Connection"/> instance with the current configuration.
- /// </summary>
- /// <returns>The configured <see cref="Connection"/> instance.</returns>
- public Connection Build()
- {
- PacketPipelineBuilder<Memory<byte>, Memory<byte>, NetworkPacket> incomingPipelineBuilder =
- new PacketPipelineBuilder<Memory<byte>, Memory<byte>, NetworkPacket>();
-
- incomingPipelineBuilder.WithInputStage(memory => memory);
- foreach (Func<Memory<byte>, Memory<byte>> stage in incomingPipelineStages)
- {
- incomingPipelineBuilder = incomingPipelineBuilder.WithIntermediateStage(stage);
- }
-
- incomingPipelineBuilder.WithOutputStage(NetworkPacket.Deserialise);
-
- PacketPipelineBuilder<NetworkPacket, Memory<byte>, Memory<byte>> outgoingPipelineBuilder =
- new PacketPipelineBuilder<NetworkPacket, Memory<byte>, Memory<byte>>();
-
- outgoingPipelineBuilder.WithInputStage(NetworkPacket.Serialise);
- foreach (Func<Memory<byte>, Memory<byte>> stage in outgoingPipelineStages)
- {
- outgoingPipelineBuilder = outgoingPipelineBuilder.WithIntermediateStage(stage);
- }
-
- outgoingPipelineBuilder.WithOutputStage(memory => memory);
-
- Connection connection = new Connection(
- incomingPipelineBuilder.Build(),
- outgoingPipelineBuilder.Build(),
- poolingSettings?.ObjectPoolSize ?? DefaultPoolingSettings.ObjectPoolSize,
- poolingSettings?.PreallocateBuffers ?? DefaultPoolingSettings.PreallocateBuffers,
- loggingSettings?.LoggingStream ?? DefaultLoggingSettings.LoggingStream,
- loggingSettings?.MinimumLevel ?? DefaultLoggingSettings.MinimumLevel);
-
- return connection;
- }
-
- /// <summary>
- /// Adds an extra pipeline stage to the currently configured incoming packet pipeline, at the given index.
- /// </summary>
- /// <param name="transform">
- /// The transformation that should be applied when a packet passes through the pipeline.
- /// </param>
- /// <param name="index">The position in the pipeline at which to place the transform.</param>
- /// <returns>The builder instance for further configuration.</returns>
- public ConnectionBuilder WithIncomingPipelineStage(in Func<Memory<byte>, Memory<byte>> transform, int index)
- {
- incomingPipelineStages.Insert(index, transform);
- return this;
- }
-
- /// <summary>
- /// Sets the logging settings for the currently configured connection.
- /// </summary>
- /// <param name="settings">The logging settings to use.</param>
- /// <returns>The builder instance for further configuration.</returns>
- public ConnectionBuilder WithLogging(LoggingSettings settings)
- {
- loggingSettings = settings;
- return this;
- }
-
- /// <summary>
- /// Adds an extra pipeline stage to the currently configured outgoing packet pipeline, at the given index.
- /// </summary>
- /// <param name="transform">
- /// The transformation that should be applied when a packet passes through the pipeline.
- /// </param>
- /// <param name="index">The position in the pipeline at which to place the transform.</param>
- /// <returns>The builder instance for further configuration.</returns>
- public ConnectionBuilder WithOutgoingPipelineStage(in Func<Memory<byte>, Memory<byte>> transform, int index)
- {
- outgoingPipelineStages.Insert(index, transform);
- return this;
- }
-
- /// <summary>
- /// Sets the pooling settings for the currently configured connection.
- /// </summary>
- /// <param name="settings">The pooling settings to use.</param>
- /// <returns>The builder instance for further configuration.</returns>
- public ConnectionBuilder WithPooling(PoolingSettings settings)
- {
- poolingSettings = settings;
- return this;
- }
-
- /// <summary>
- /// Holds settings for configuring a connection's logging.
- /// </summary>
- public readonly struct LoggingSettings
- {
- /// <summary>
- /// The stream to which messages will be logged.
- /// </summary>
- public readonly Stream LoggingStream;
-
- /// <summary>
- /// The minimum severity that a log message must have to be recorded.
- /// </summary>
- public readonly LogLevel MinimumLevel;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="LoggingStream"/> struct.
- /// </summary>
- /// <param name="stream">The stream to which messages will be logged..</param>
- /// <param name="minimumLevel">The minimum severity that a log message must have to be recorded.</param>
- public LoggingSettings(Stream stream, LogLevel minimumLevel)
- {
- LoggingStream = stream;
- MinimumLevel = minimumLevel;
- }
- }
-
- /// <summary>
- /// Holds settings for configuring a connection's buffer pooling.
- /// </summary>
- public readonly struct PoolingSettings
- {
- /// <summary>
- /// The number of objects that will be held in the object pools.
- /// </summary>
- public readonly int ObjectPoolSize;
-
- /// <summary>
- /// Whether the buffers for receiving messages should be preallocated.
- /// </summary>
- public readonly bool PreallocateBuffers;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="PoolingSettings"/> struct.
- /// </summary>
- /// <param name="poolSize">The number of objects that will be held in the object pools.</param>
- /// <param name="preallocateBuffers">Whether the buffers for receiving messages should be preallocated.</param>
- public PoolingSettings(int poolSize, bool preallocateBuffers)
- {
- ObjectPoolSize = poolSize;
- PreallocateBuffers = preallocateBuffers;
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ConnectionBuilderExtensions.cs b/NetSharp/NetSharp/Deprecated/ConnectionBuilderExtensions.cs
@@ -1,27 +0,0 @@
-using System;
-using System.IO;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides additional methods and functionality to the <see cref="ConnectionBuilder"/> class.
- /// </summary>
- public static class ConnectionBuilderExtensions
- {
- public static ConnectionBuilder AppendIncomingPipelineStage(this ConnectionBuilder instance,
- in Func<Memory<byte>, Memory<byte>> transform)
- => instance.WithIncomingPipelineStage(transform, instance.IncomingPacketPipelineStageCount);
-
- public static ConnectionBuilder AppendOutgoingPipelineStage(this ConnectionBuilder instance,
- in Func<Memory<byte>, Memory<byte>> transform)
- => instance.WithOutgoingPipelineStage(transform, instance.OutgoingPacketPipelineStageCount);
-
- public static ConnectionBuilder WithLogging(this ConnectionBuilder instance,
- Stream loggingStream, LogLevel minimumLogLevel)
- => instance.WithLogging(new ConnectionBuilder.LoggingSettings(loggingStream, minimumLogLevel));
-
- public static ConnectionBuilder WithPooling(this ConnectionBuilder instance,
- int poolSize, bool preallocateBuffers)
- => instance.WithPooling(new ConnectionBuilder.PoolingSettings(poolSize, preallocateBuffers));
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ConnectionExtensions.cs b/NetSharp/NetSharp/Deprecated/ConnectionExtensions.cs
@@ -1,73 +0,0 @@
-using NetSharp.Utils;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides additional methods and functionality to the <see cref="Connection"/> class.
- /// </summary>
- public static class ConnectionExtensions
- {
- public static Task<TransmissionResult> ReceiveAsync(this Connection instance,
- EndPoint remoteEndPoint, Memory<byte> inputBuffer, SocketFlags flags)
- => instance.ReceiveAsync(inputBuffer, flags, Timeout.InfiniteTimeSpan);
-
- public static Task<TransmissionResult> ReceiveFromAsync(this Connection instance,
- EndPoint remoteEndPoint, Memory<byte> inputBuffer, SocketFlags flags)
- => instance.ReceiveFromAsync(remoteEndPoint, inputBuffer, flags, Timeout.InfiniteTimeSpan);
-
- public static ValueTask<int> SendAsync(this Connection instance,
- EndPoint remoteEndPoint, Memory<byte> outputBuffer, SocketFlags flags)
- => instance.SendAsync(outputBuffer, flags, Timeout.InfiniteTimeSpan);
-
- public static ValueTask<int> SendToAsync(this Connection instance,
- EndPoint remoteEndPoint, Memory<byte> outputBuffer, SocketFlags flags)
- => instance.SendToAsync(remoteEndPoint, outputBuffer, flags, Timeout.InfiniteTimeSpan);
-
- /// <summary>
- /// Attempts to synchronously bind the underlying socket to the given local endpoint. Blocks.
- /// If the timeout is exceeded the binding attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="localEndPoint">The local endpoint to bind to.</param>
- /// <param name="timeout">The timeout within which to attempt the binding.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- public static bool TryBind(this Connection instance,
- EndPoint localEndPoint, TimeSpan timeout)
- => instance.TryBindAsync(localEndPoint, timeout).Result;
-
- public static bool TryBind(this Connection instance,
- EndPoint localEndPoint)
- => instance.TryBindAsync(localEndPoint, Timeout.InfiniteTimeSpan).Result;
-
- public static Task<bool> TryBindAsync(this Connection instance,
- EndPoint localEndPoint)
- => instance.TryBindAsync(localEndPoint, Timeout.InfiniteTimeSpan);
-
- public static bool TryConnect(this Connection instance,
- EndPoint remoteEndPoint)
- => instance.TryConnectAsync(remoteEndPoint, Timeout.InfiniteTimeSpan).Result;
-
- public static bool TryConnect(this Connection instance,
- EndPoint remoteEndPoint, TimeSpan timeout)
- => instance.TryConnectAsync(remoteEndPoint, timeout).Result;
-
- public static Task<bool> TryConnectAsync(this Connection instance,
- EndPoint remoteEndPoint)
- => instance.TryConnectAsync(remoteEndPoint, Timeout.InfiniteTimeSpan);
-
- public static bool TryDisconnect(this Connection instance)
- => instance.TryDisconnectAsync(Timeout.InfiniteTimeSpan).Result;
-
- public static bool TryDisconnect(this Connection instance,
- TimeSpan timeout)
- => instance.TryDisconnectAsync(timeout).Result;
-
- public static Task<bool> TryDisconnectAsync(this Connection instance)
- => instance.TryDisconnectAsync(Timeout.InfiniteTimeSpan);
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Constants.cs b/NetSharp/NetSharp/Deprecated/Constants.cs
@@ -1,15 +0,0 @@
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Holds internal default configurations and constants.
- /// </summary>
- internal static class Constants
- {
- /// <summary>
- /// The default port over which a connection is made.
- /// </summary>
- internal const int DefaultPort = 12374;
-
- internal const int MaximumUdpPacketBytes = 65507;
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/CryptographyHelpers.cs b/NetSharp/NetSharp/Deprecated/CryptographyHelpers.cs
@@ -1,96 +0,0 @@
-using System;
-using System.IO;
-using System.Security.Cryptography;
-using System.Text;
-
-namespace NetSharp.Deprecated
-{
- internal static class CryptographyHelpers
- {
- #region Settings
-
- private static string _hash = "SHA1";
- private static int _iterations = 2;
- private static int _keySize = 256;
- private static string _salt = "aselrias38490a32"; // Random
- private static string _vector = "8947az34awl34kjq"; // Random
-
- #endregion Settings
-
- public static string Decrypt(byte[] value, string password)
- {
- return Decrypt<AesManaged>(value, password);
- }
-
- public static string Decrypt<T>(byte[] value, string password) where T : SymmetricAlgorithm, new()
- {
- byte[] vectorBytes = Encoding.ASCII.GetBytes(_vector); // GetBytes<ASCIIEncoding>(_vector);
- byte[] saltBytes = Encoding.ASCII.GetBytes(_salt); // GetBytes<ASCIIEncoding>(_salt);
- byte[] valueBytes = value;
-
- byte[] decrypted;
- int decryptedByteCount = 0;
-
- using (T cipher = new T())
- {
- PasswordDeriveBytes _passwordBytes = new PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
- byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);
-
- cipher.Mode = CipherMode.CBC;
-
- try
- {
- using (ICryptoTransform decryptor = cipher.CreateDecryptor(keyBytes, vectorBytes))
- {
- using MemoryStream from = new MemoryStream(valueBytes);
- using CryptoStream reader = new CryptoStream(@from, decryptor, CryptoStreamMode.Read);
-
- decrypted = new byte[valueBytes.Length];
- decryptedByteCount = reader.Read(decrypted, 0, decrypted.Length);
- }
- }
- catch (Exception ex)
- {
- return String.Empty;
- }
-
- cipher.Clear();
- }
- return Encoding.UTF8.GetString(decrypted, 0, decryptedByteCount);
- }
-
- public static byte[] Encrypt(string value, string password)
- {
- return Encrypt<AesManaged>(value, password);
- }
-
- public static byte[] Encrypt<T>(string value, string password) where T : SymmetricAlgorithm, new()
- {
- byte[] vectorBytes = Encoding.ASCII.GetBytes(_vector); // GetBytes<ASCIIEncoding>(_vector);
- byte[] saltBytes = Encoding.ASCII.GetBytes(_salt); // GetBytes<ASCIIEncoding>(_salt);
- byte[] valueBytes = Encoding.UTF8.GetBytes(value); // GetBytes<UTF8Encoding>(value);
-
- byte[] encrypted;
- using (T cipher = new T())
- {
- PasswordDeriveBytes _passwordBytes =
- new PasswordDeriveBytes(password, saltBytes, _hash, _iterations);
- byte[] keyBytes = _passwordBytes.GetBytes(_keySize / 8);
-
- cipher.Mode = CipherMode.CBC;
-
- using (ICryptoTransform encryptor = cipher.CreateEncryptor(keyBytes, vectorBytes))
- {
- using MemoryStream to = new MemoryStream();
- using CryptoStream writer = new CryptoStream(to, encryptor, CryptoStreamMode.Write);
-
- writer.Write(valueBytes, 0, valueBytes.Length);
- writer.FlushFinalBlock();
- encrypted = to.ToArray();
- }
- cipher.Clear();
- }
- return encrypted;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/DefaultSocketOptions.cs b/NetSharp/NetSharp/Deprecated/DefaultSocketOptions.cs
@@ -1,46 +0,0 @@
-using System;
-using System.Net.Sockets;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows for manipulation of socket options.
- /// </summary>
- public sealed class DefaultSocketOptions : SocketOptions
- {
- /// <inheritdoc />
- public DefaultSocketOptions(ref Socket socket) : base(ref socket)
- {
- }
-
- /// <inheritdoc />
- /// <exception cref="NotSupportedException">
- /// This property is not supported when using the default socket option manager.
- /// </exception>
- public override int HopLimit
- {
- get { throw new NotSupportedException("This property is not supported in the default socket options manager."); }
- set { throw new NotSupportedException("This property is not supported in the default socket options manager."); }
- }
-
- /// <inheritdoc />
- /// <exception cref="NotSupportedException">
- /// This property is not supported when using the default socket option manager.
- /// </exception>
- public override bool IsRoutingEnabled
- {
- get { throw new NotSupportedException("This property is not supported in the default socket options manager."); }
- set { throw new NotSupportedException("This property is not supported in the default socket options manager."); }
- }
-
- /// <inheritdoc />
- /// <exception cref="NotSupportedException">
- /// This property is not supported when using the default socket option manager.
- /// </exception>
- public override bool UseLoopback
- {
- get { throw new NotSupportedException("This property is not supported in the default socket options manager."); }
- set { throw new NotSupportedException("This property is not supported in the default socket options manager."); }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/IClient.cs b/NetSharp/NetSharp/Deprecated/IClient.cs
@@ -1,88 +0,0 @@
-using System;
-using System.Net;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes a client capable of asynchronous communication with an <see cref="IServer"/> connection.
- /// </summary>
- public interface IClient
- {
- /// <summary>
- /// Signifies that a connection with the remote endpoint has been made.
- /// </summary>
- public event Action<EndPoint>? Connected;
-
- /// <summary>
- /// Signifies that the connection with the remote endpoint was severed.
- /// </summary>
- public event Action<EndPoint>? Disconnected;
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint asynchronously. Does not block, and observes
- /// a timeout of the given length.
- /// timeout.
- /// </summary>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- /// <param name="timeout">The timeout after which to cancel the transmission attempt.</param>
- /// <returns>Whether the transmission attempt was successful.</returns>
- public Task<bool> SendBytesAsync(byte[] buffer, TimeSpan timeout);
-
- /// <summary>
- /// Sends the given byte buffer to the connected remote endpoint and waits for the response asynchronously.
- /// Does not block, and observes a timeout of the given length.
- /// timeout.
- /// </summary>
- /// <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- /// <param name="timeout">
- /// The timeout after which to cancel the transmission attempt. This timeout is reused by both the 'send' and
- /// 'receive' parts of the transmission attempt, such that the maximum timeout is equal to 2 times the given
- /// value.
- /// </param>
- /// <returns>The byte buffer received as a response to the sent buffer.</returns>
- public Task<byte[]> SendBytesWithResponseAsync(byte[] buffer, TimeSpan timeout);
-
- /// <summary>
- /// Sends the given request and listens for a response of the given type asynchronously. Does not block.
- /// Cancels the operation if the given timeout is exceeded
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <typeparam name="Rep">The type of response packet to receive.</typeparam>
- /// <param name="request">The request packet to send.</param>
- /// <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- /// <returns>The received instance.</returns>
- public Task<Rep> SendComplexAsync<Req, Rep>(Req request, TimeSpan timeout)
- where Req : IRequestPacket, new() where Rep : IResponsePacket<Req>, new();
-
- /// <summary>
- /// Sends the given request asynchronously without listening for a response, not blocking until it is sent.
- /// Cancels the operation if the given timeout is exceeded.
- /// </summary>
- /// <typeparam name="Req">The type of request packet to send.</typeparam>
- /// <param name="request">The request packet to send.</param>
- /// <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- /// <returns>Whether the transmission attempt was successful.</returns>
- public Task<bool> SendSimpleAsync<Req>(Req request, TimeSpan timeout) where Req : IRequestPacket, new();
-
- /// <summary>
- /// Attempts to asynchronously bind the underlying socket to the given local address and port. Does not block.
- /// If the timeout is exceeded the binding attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- /// <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- /// <param name="timeout">The timeout within which to attempt the binding.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- public Task<bool> TryBindAsync(IPAddress? localAddress, int? localPort, TimeSpan timeout);
-
- /// <summary>
- /// Attempts to connect asynchronously to the remote <see cref="Server"/> at the given <see cref="IPAddress"/>
- /// and over the given port. If the timeout is exceeded the connection attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="remoteAddress">The remote IP address to connect to.</param>
- /// <param name="remotePort">The remote port to connect over.</param>
- /// <param name="timeout">The timeout within which to attempt the connection.</param>
- /// <returns>Whether the connection was successful or not.</returns>
- public Task<bool> TryConnectAsync(IPAddress remoteAddress, int remotePort, TimeSpan timeout);
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/INetworkSerialisable.cs b/NetSharp/NetSharp/Deprecated/INetworkSerialisable.cs
@@ -1,22 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes an object that can be serialised to be sent across the network.
- /// </summary>
- public interface INetworkSerialisable
- {
- /// <summary>
- /// Deserialises the object instance from a byte array.
- /// </summary>
- /// <param name="serialisedObject">The memory containing the serialised object instance.</param>
- void Deserialise(ReadOnlyMemory<byte> serialisedObject);
-
- /// <summary>
- /// Serialises the object instance into a byte array.
- /// </summary>
- /// <returns>The memory containing the serialised object instance.</returns>
- Memory<byte> Serialise();
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/IPacket.cs b/NetSharp/NetSharp/Deprecated/IPacket.cs
@@ -1,18 +0,0 @@
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes the methods and properties that every packet
- /// </summary>
- public interface IPacket
- {
- /// <summary>
- /// Allows for custom fields to be converted from their serialised format, after being received from the network.
- /// </summary>
- void AfterDeserialisation();
-
- /// <summary>
- /// Allows for custom fields to be converted into another format prior to being sent via the network.
- /// </summary>
- void BeforeSerialisation();
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/IPacketHandler.cs b/NetSharp/NetSharp/Deprecated/IPacketHandler.cs
@@ -1,51 +0,0 @@
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes a class capable of registering and deregistering packet handlers, and capable of
- /// handling incoming packets according to the currently registered packet handlers.
- /// </summary>
- public interface IPacketHandler
- {
- /// <summary>
- /// Attempts to deregister the complex packet handler delegate for all packets of the given type. If a handler
- /// method doesn't exist for the given packet type, <paramref name="oldHandlerDelegate"/> will be <c>default</c>.
- /// </summary>
- /// <typeparam name="Req">The type of request packet for which to deregister the handler delegate.</typeparam>
- /// <typeparam name="Rep">The type of response packet that is generated by the delegate method.</typeparam>
- /// <param name="oldHandlerDelegate">The old handler delegate method that was previously registered.</param>
- /// <returns>Whether the packet handler delegate was successfully deregistered.</returns>
- public bool TryDeregisterComplexPacketHandler<Req, Rep>(out ComplexPacketHandler<Req, Rep>? oldHandlerDelegate)
- where Req : class, IRequestPacket, new() where Rep : class, IResponsePacket<Req>, new();
-
- /// <summary>
- /// Attempts to deregister the simple packet handler delegate for all packets of the given type. If a handler
- /// method doesn't exist for the given packet type, <paramref name="oldHandlerDelegate"/> will be <c>default</c>.
- /// </summary>
- /// <typeparam name="Req">The type of request packet for which to deregister the handler delegate.</typeparam>
- /// <param name="oldHandlerDelegate">The old handler delegate method that was previously registered.</param>
- /// <returns>Whether the packet handler delegate was successfully deregistered.</returns>
- public bool TryDeregisterSimplePacketHandler<Req>(out SimplePacketHandler<Req>? oldHandlerDelegate)
- where Req : class, IRequestPacket, new();
-
- /// <summary>
- /// Attempts to register a complex packet handler delegate for all packets of the given type. If a handler
- /// method already exists for the given packet type, it will be updated and replaced with the given one.
- /// </summary>
- /// <typeparam name="Req">The type of request packet for which to register the handler delegate.</typeparam>
- /// <typeparam name="Rep">The type of response packet that is generated by the delegate method.</typeparam>
- /// <param name="handlerDelegate">The delegate method to register as the complex packet handler.</param>
- /// <returns>Whether the packet handler delegate was successfully registered.</returns>
- public bool TryRegisterComplexPacketHandler<Req, Rep>(ComplexPacketHandler<Req, Rep> handlerDelegate)
- where Req : class, IRequestPacket, new() where Rep : class, IResponsePacket<Req>, new();
-
- /// <summary>
- /// Attempts to register a simple packet handler delegate for all packets of the given type. If a handler
- /// method already exists for the given packet type, it will be updated and replaced with the given one.
- /// </summary>
- /// <typeparam name="Req">The type of request packet for which to register the handler delegate.</typeparam>
- /// <param name="handlerDelegate">The delegate method to register as the simple packet handler.</param>
- /// <returns>Whether the packet handler delegate was successfully registered.</returns>
- public bool TryRegisterSimplePacketHandler<Req>(SimplePacketHandler<Req> handlerDelegate)
- where Req : class, IRequestPacket, new();
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/IRequestPacket.cs b/NetSharp/NetSharp/Deprecated/IRequestPacket.cs
@@ -1,9 +0,0 @@
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes a request packet.
- /// </summary>
- public interface IRequestPacket : IPacket, INetworkSerialisable
- {
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/IResponsePacket.cs b/NetSharp/NetSharp/Deprecated/IResponsePacket.cs
@@ -1,14 +0,0 @@
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes a response packet to a request packet.
- /// </summary>
- /// <typeparam name="TReq">The request packet that this type is a response to.</typeparam>
- public interface IResponsePacket<out TReq> : IPacket, INetworkSerialisable where TReq : IRequestPacket
- {
- /// <summary>
- /// The request packet that was handled with this response packet.
- /// </summary>
- TReq RequestPacket { get; }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/IServer.cs b/NetSharp/NetSharp/Deprecated/IServer.cs
@@ -1,44 +0,0 @@
-using System;
-using System.Net;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Describes a server capable of asynchronously handling multiple <see cref="IClient"/> connections at once.
- /// </summary>
- public interface IServer
- {
- /// <summary>
- /// Signifies that a connection with a remote endpoint has been made.
- /// </summary>
- public event Action<EndPoint>? ClientConnected;
-
- //protected IResponsePacket<IRequestPacket> DeserialiseResponsePacket(in Packet)
- /// <summary>
- /// Signifies that a connection with a remote endpoint has been lost.
- /// </summary>
- public event Action<EndPoint>? ClientDisconnected;
-
- /// <summary>
- /// Signifies that the server was started and clients will start being accepted.
- /// </summary>
- public event Action? ServerStarted;
-
- /// <summary>
- /// Signifies that the server was stopped and clients will stop being accepted.
- /// </summary>
- public event Action? ServerStopped;
-
- /// <summary>
- /// Starts the server asynchronously and starts accepting client connections. Does not block.
- /// </summary>
- /// <param name="localEndPoint">The local endpoint to bind to.</param>
- public Task RunAsync(EndPoint localEndPoint);
-
- /// <summary>
- /// Shuts down the server.
- /// </summary>
- public void Shutdown();
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Logger.cs b/NetSharp/NetSharp/Deprecated/Logger.cs
@@ -1,194 +0,0 @@
-using System;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Specifies the severity level of a log message.
- /// </summary>
- public enum LogLevel
- {
- /// <summary>
- /// The logged message contains some information. Lowest severity.
- /// </summary>
- Info,
-
- /// <summary>
- /// The logged message contains a warning. Higher severity.
- /// </summary>
- Warn,
-
- /// <summary>
- /// The logged message contains details about an error. Higher severity.
- /// </summary>
- Error,
-
- /// <summary>
- /// The logged message contains details about an exception. Highest severity.
- /// </summary>
- Exception
- }
-
- /// <summary>
- /// A simple logger capable of writing text to a stream.
- /// </summary>
- public readonly struct Logger : IDisposable
- {
- /// <summary>
- /// The stream to which messages will be logged.
- /// </summary>
- private readonly Stream loggingStream;
-
- /// <summary>
- /// The minimum severity that log messages need to be logged to the underlying stream.
- /// </summary>
- private readonly LogLevel minimumSeverity;
-
- /// <summary>
- /// The text writer we will use to log messages to the underlying stream.
- /// </summary>
- private readonly StreamWriter writer;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="Logger"/> struct.
- /// </summary>
- /// <param name="outputStream">The stream that the logger instance should log messages to.</param>
- /// <param name="minimumLogSeverity">The minimum log level that will be logged to the output stream.</param>
- public Logger(Stream outputStream, LogLevel minimumLogSeverity = LogLevel.Info)
- {
- loggingStream = outputStream;
- writer = new StreamWriter(loggingStream, Encoding.Default) { AutoFlush = true };
-
- minimumSeverity = minimumLogSeverity;
- }
-
- /// <inheritdoc />
- public void Dispose()
- {
- loggingStream.Dispose();
- writer.Dispose();
- }
-
- /// <summary>
- /// Logs a message to the underlying stream, along with the given exception and at the given severity.
- /// </summary>
- /// <param name="message">The message that should be logged.</param>
- /// <param name="exception">The exception that occurred (if any).</param>
- /// <param name="severity">The severity of the message that is being logged.</param>
- public void Log(string message, Exception? exception, LogLevel severity)
- {
- if (severity < minimumSeverity) return;
-
- string severityTag = severity switch
- {
- LogLevel.Info => "Info ",
- LogLevel.Warn => "Warn ",
- LogLevel.Error => "Error",
- LogLevel.Exception => "Excep",
- _ => "Info "
- };
-
- writer.WriteLine($"[{severityTag}] {message} {exception}");
- }
-
- /// <summary>
- /// Logs a message asynchronously to the underlying stream, along with the given exception and at the given severity.
- /// </summary>
- /// <param name="message">The message that should be logged.</param>
- /// <param name="exception">The exception that occurred (if any).</param>
- /// <param name="severity">The severity of the message that is being logged.</param>
- public async Task LogAsync(string message, Exception? exception, LogLevel severity)
- {
- if (loggingStream.Equals(Stream.Null))
- {
- // ignore log request if the underlying stream is null
- return;
- }
-
- if (!exception?.Equals(default) ?? false)
- {
- severity = LogLevel.Exception;
- }
-
- if (severity >= minimumSeverity)
- {
- string severityTag = severity switch
- {
- LogLevel.Info => "Info ",
- LogLevel.Warn => "Warn ",
- LogLevel.Error => "Error",
- LogLevel.Exception => "Excep",
- _ => "Info "
- };
-
- await writer.WriteLineAsync($"[{severityTag}] {message} {exception}");
- }
- }
-
- /// <summary>
- /// Logs an error to the underlying stream, with severity <see cref="LogLevel.Info"/>.
- /// </summary>
- /// <param name="message">The error that should be logged.</param>
- public void LogError(string message) => Log(message, null, LogLevel.Error);
-
- /// <summary>
- /// Logs an error to the underlying stream asynchronously, with severity <see cref="LogLevel.Error"/>.
- /// </summary>
- /// <param name="message">The error that should be logged.</param>
- public async Task LogErrorAsync(string message) => await LogAsync(message, null, LogLevel.Error);
-
- /// <summary>
- /// Logs an exception to the underlying stream, with severity <see cref="LogLevel.Exception"/>.
- /// </summary>
- /// <param name="exception">The exception that should be logged.</param>
- public void LogException(Exception exception) => Log("", exception, LogLevel.Exception);
-
- /// <summary>
- /// Logs an exception to the underlying stream, along with a short debug message, with severity
- /// <see cref="LogLevel.Exception"/>.
- /// </summary>
- /// <param name="message">The debug message that should be logged with the exception.</param>
- /// <param name="exception">The exception that should be logged.</param>
- public void LogException(string message, Exception exception) => Log(message, exception, LogLevel.Exception);
-
- /// <summary>
- /// Logs an exception to the underlying stream asynchronously, with severity <see cref="LogLevel.Exception"/>.
- /// </summary>
- /// <param name="exception">The exception that should be logged.</param>
- public async Task LogExceptionAsync(Exception exception) => await LogAsync("", exception, LogLevel.Exception);
-
- /// <summary>
- /// Logs an exception to the underlying stream asynchronously, along with a short debug message, with severity
- /// <see cref="LogLevel.Exception"/>.
- /// </summary>
- /// <param name="message">The debug message that should be logged with the exception.</param>
- /// <param name="exception">The exception that should be logged.</param>
- public async Task LogExceptionAsync(string message, Exception exception) => await LogAsync(message, exception, LogLevel.Exception);
-
- /// <summary>
- /// Logs a message to the underlying stream, with severity <see cref="LogLevel.Info"/>.
- /// </summary>
- /// <param name="message">The message that should be logged.</param>
- public void LogMessage(string message) => Log(message, null, LogLevel.Info);
-
- /// <summary>
- /// Logs a message to the underlying stream asynchronously, with severity <see cref="LogLevel.Info"/>.
- /// </summary>
- /// <param name="message">The message that should be logged.</param>
- public async Task LogMessageAsync(string message) => await LogAsync(message, null, LogLevel.Info);
-
- /// <summary>
- /// Logs a warning to the underlying stream, with severity <see cref="LogLevel.Info"/>.
- /// </summary>
- /// <param name="message">The warning that should be logged.</param>
- public void LogWarning(string message) => Log(message, null, LogLevel.Warn);
-
- /// <summary>
- /// Logs a warning to the underlying stream asynchronously, with severity <see cref="LogLevel.Warn"/>.
- /// </summary>
- /// <param name="message">The warning that should be logged.</param>
- public async Task LogWarningAsync(string message) => await LogAsync(message, null, LogLevel.Warn);
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/NetworkErrorCode.cs b/NetSharp/NetSharp/Deprecated/NetworkErrorCode.cs
@@ -1,18 +0,0 @@
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Enumerates the possible error codes for network operations, being held in the packet.
- /// </summary>
- public enum NetworkErrorCode : uint
- {
- /// <summary>
- /// Signifies that there was no error during transmission.
- /// </summary>
- Ok = 0,
-
- /// <summary>
- /// A generic error occurred during packet transmission.
- /// </summary>
- Error = 1 << 1,
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/NetworkPacket.cs b/NetSharp/NetSharp/Deprecated/NetworkPacket.cs
@@ -1,218 +0,0 @@
-using NetSharp.Deprecated.Conversion;
-
-using System;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Represents a low-level packet that is transmitted over the network.
- /// </summary>
- public readonly struct NetworkPacket
- {
- /// <summary>
- /// Initialises a new instance of the <see cref="NetworkPacket"/> struct.
- /// </summary>
- /// <param name="data">The data that should be transmitted in the packet.</param>
- /// <param name="header">The header for the packet.</param>
- /// <param name="footer">The footer for the packet.</param>
- private NetworkPacket(ReadOnlyMemory<byte> data, NetworkPacketHeader header, NetworkPacketFooter footer)
- {
- Header = header;
-
- DataBuffer = data;
-
- Footer = footer;
- }
-
- /// <summary>
- /// The number of bytes allocated in each packet for user data.
- /// </summary>
- public const int DataSegmentSize = PacketSize - HeaderSize - FooterSize;
-
- /// <summary>
- /// The number of bytes taken up in each packet by its footer.
- /// </summary>
- public const int FooterSize = NetworkPacketFooter.Size;
-
- /// <summary>
- /// The number of bytes taken up in each packet by its header.
- /// </summary>
- public const int HeaderSize = NetworkPacketHeader.Size;
-
- /// <summary>
- /// The size of each packet, including its header, footer, and data segment.
- /// </summary>
- public const int PacketSize = 4096;
-
- /// <summary>
- /// The data held in this packet.
- /// </summary>
- public readonly ReadOnlyMemory<byte> DataBuffer;
-
- public readonly NetworkPacketFooter Footer;
- public readonly NetworkPacketHeader Header;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="NetworkPacket"/> struct.
- /// </summary>
- /// <param name="data">The data that should be transmitted in the packet.</param>
- /// <param name="dataLength">The number of bytes that are held in the given data buffer.</param>
- /// <param name="type">The packet type.</param>
- /// <param name="errorCode">The error code associated with this transmission.</param>
- /// <param name="hasSucceedingPacket">Whether this packet has a succeeding packet in the packet chain.</param>
- public NetworkPacket(ReadOnlyMemory<byte> data, int dataLength, uint type, NetworkErrorCode errorCode, bool hasSucceedingPacket)
- {
- Header = new NetworkPacketHeader(type, errorCode, dataLength);
-
- DataBuffer = data;
-
- Footer = new NetworkPacketFooter(hasSucceedingPacket);
- }
-
- /// <summary>
- /// Deserialises the given buffer into a packet instance.
- /// </summary>
- /// <param name="buffer">The byte buffer to serialise.</param>
- /// <returns>The deserialised packet instance.</returns>
- public static NetworkPacket Deserialise(Memory<byte> buffer)
- {
- Span<byte> serialisedPacketHeader = buffer.Slice(0, HeaderSize).Span;
- NetworkPacketHeader header = NetworkPacketHeader.Deserialise(serialisedPacketHeader);
-
- Span<byte> serialisedPacketFooter = buffer.Slice(HeaderSize + DataSegmentSize, FooterSize).Span;
- NetworkPacketFooter footer = NetworkPacketFooter.Deserialise(serialisedPacketFooter);
-
- Memory<byte> serialisedInstanceData = buffer.Slice(HeaderSize, DataSegmentSize);
-
- return new NetworkPacket(serialisedInstanceData, header, footer);
- }
-
- /// <summary>
- /// Serialises the given packet instance to a new byte buffer.
- /// </summary>
- /// <param name="instance">The packet instance to serialise.</param>
- /// <returns>The byte buffer that represents the packet instance.</returns>
- public static Memory<byte> Serialise(NetworkPacket instance)
- {
- byte[] buffer = new byte[PacketSize];
- SerialiseToBuffer(buffer, instance);
- return buffer;
- }
-
- /// <summary>
- /// Serialises the given packet instance into the given byte buffer.
- /// </summary>
- /// <param name="buffer">
- /// The buffer to which the instance should be serialised. Must be at least of size <see cref="PacketSize"/>.
- /// </param>
- /// <param name="instance">The packet instance to serialise.</param>
- /// <exception cref="ArgumentException">Thrown if the given buffer is too small.</exception>
- public static void SerialiseToBuffer(Memory<byte> buffer, NetworkPacket instance)
- {
- if (buffer.Length < PacketSize)
- {
- throw new ArgumentException("Given buffer is too small to serialise the packet instance into.", nameof(buffer));
- }
-
- Span<byte> serialisedPacketHeader = buffer.Slice(0, HeaderSize).Span;
- NetworkPacketHeader.Serialise(serialisedPacketHeader, instance.Header);
-
- Span<byte> serialisedPacketFooter = buffer.Slice(HeaderSize + DataSegmentSize, FooterSize).Span;
- NetworkPacketFooter.Serialise(serialisedPacketFooter, instance.Footer);
-
- Memory<byte> serialisedInstanceData = buffer.Slice(HeaderSize, DataSegmentSize);
- instance.DataBuffer.CopyTo(serialisedInstanceData);
- }
- }
-
- // TODO: Document
- public readonly struct NetworkPacketFooter
- {
- private const int PacketHasNextStart = 0;
-
- /// <summary>
- /// The number of bytes taken up by a packet footer.
- /// </summary>
- public const int Size = sizeof(bool);
-
- public readonly bool HasSucceedingPacket;
-
- public NetworkPacketFooter(bool hasSucceedingPacket)
- {
- HasSucceedingPacket = hasSucceedingPacket;
- }
-
- public static NetworkPacketFooter Deserialise(Span<byte> buffer)
- {
- Span<byte> serialisedHasNextFlag = buffer.Slice(PacketHasNextStart, sizeof(bool));
-
- return new NetworkPacketFooter(
- EndianAwareBitConverter.ToBoolean(serialisedHasNextFlag));
- }
-
- public static void Serialise(Span<byte> buffer, NetworkPacketFooter instance)
- {
- Span<byte> serialisedHasNextFlag = buffer.Slice(PacketHasNextStart, sizeof(bool));
-
- EndianAwareBitConverter.GetBytes(instance.HasSucceedingPacket).CopyTo(serialisedHasNextFlag);
- }
- }
-
- // TODO: Document
- public readonly struct NetworkPacketHeader
- {
- private const int PacketDataLengthStart = 2 * sizeof(uint);
- private const int PacketErrorCodeStart = sizeof(uint);
- private const int PacketTypeStart = 0;
-
- /// <summary>
- /// The number of bytes taken up by a packet header.
- /// </summary>
- public const int Size = sizeof(uint) + sizeof(uint) + sizeof(int);
-
- /// <summary>
- /// The number of bytes of data held in the packet.
- /// </summary>
- public readonly int DataLength;
-
- /// <summary>
- /// The error code for this packet.
- /// </summary>
- public readonly NetworkErrorCode ErrorCode;
-
- /// <summary>
- /// The packet type.
- /// </summary>
- public readonly uint Type;
-
- public NetworkPacketHeader(uint packetType, NetworkErrorCode packetErrorCode, int packetDataLength)
- {
- Type = packetType;
- ErrorCode = packetErrorCode;
- DataLength = packetDataLength;
- }
-
- public static NetworkPacketHeader Deserialise(Span<byte> buffer)
- {
- Span<byte> serialisedType = buffer.Slice(PacketTypeStart, sizeof(uint));
- Span<byte> serialisedErrorCode = buffer.Slice(PacketErrorCodeStart, sizeof(uint));
- Span<byte> serialisedDataLength = buffer.Slice(PacketDataLengthStart, sizeof(int));
-
- return new NetworkPacketHeader(
- EndianAwareBitConverter.ToUInt32(serialisedType),
- (NetworkErrorCode)EndianAwareBitConverter.ToUInt32(serialisedErrorCode),
- EndianAwareBitConverter.ToInt32(serialisedDataLength));
- }
-
- public static void Serialise(Span<byte> buffer, NetworkPacketHeader instance)
- {
- Span<byte> serialisedType = buffer.Slice(PacketTypeStart, sizeof(uint));
- Span<byte> serialisedErrorCode = buffer.Slice(PacketErrorCodeStart, sizeof(uint));
- Span<byte> serialisedDataLength = buffer.Slice(PacketDataLengthStart, sizeof(int));
-
- EndianAwareBitConverter.GetBytes(instance.Type).CopyTo(serialisedType);
- EndianAwareBitConverter.GetBytes((uint)instance.ErrorCode).CopyTo(serialisedErrorCode);
- EndianAwareBitConverter.GetBytes(instance.DataLength).CopyTo(serialisedDataLength);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/PacketPipeline.cs b/NetSharp/NetSharp/Deprecated/PacketPipeline.cs
@@ -1,65 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Represents a pipeline of transformations that packets must undergo.
- /// </summary>
- /// <typeparam name="TInput">The type of packet the pipeline receives.</typeparam>
- /// <typeparam name="TIntermediate">The type of packet the pipeline internally handles.</typeparam>
- /// <typeparam name="TOutput">The type of packet the pipeline outputs.</typeparam>
- // TODO: Implement a packet pipeline, with multiple transform stages to allow encryption, compression, and various other bytewise manipulation stages.
- internal readonly struct PacketPipeline<TInput, TIntermediate, TOutput>
- {
- private readonly PacketPipelineStage<TInput, TIntermediate> pipelineInputStage;
- private readonly IReadOnlyCollection<PacketPipelineStage<TIntermediate, TIntermediate>> pipelineIntermediateStages;
- private readonly PacketPipelineStage<TIntermediate, TOutput> pipelineOutputStage;
-
- internal PacketPipeline(
- PacketPipelineStage<TInput, TIntermediate> firstStage,
- PacketPipelineStage<TIntermediate, TOutput> lastStage,
- IReadOnlyCollection<PacketPipelineStage<TIntermediate, TIntermediate>> intermediateStages)
- {
- pipelineInputStage = firstStage;
- pipelineOutputStage = lastStage;
-
- pipelineIntermediateStages = intermediateStages;
- }
-
- /// <summary>
- /// Passes the given packet through the pipeline.
- /// </summary>
- /// <param name="inputPacket">The incoming packet.</param>
- /// <returns>The outgoing transformed packet.</returns>
- internal TOutput ProcessPacket(TInput inputPacket)
- {
- TIntermediate intermediatePacket = pipelineInputStage.Process(inputPacket);
-
- intermediatePacket = pipelineIntermediateStages.Aggregate(intermediatePacket, (current, stage) => stage.Process(current));
-
- return pipelineOutputStage.Process(intermediatePacket);
- }
- }
-
- /// <summary>
- /// Represents a single transformation applied to a packet traveling through the pipeline.
- /// </summary>
- /// <typeparam name="TInput">The type the transformation takes as input.</typeparam>
- /// <typeparam name="TOutput">The type the transformation produces as output.</typeparam>
- internal readonly struct PacketPipelineStage<TInput, TOutput>
- {
- private readonly Func<TInput, TOutput> stageDelegate;
-
- internal PacketPipelineStage(in Func<TInput, TOutput> stageProcessingDelegate)
- {
- stageDelegate = stageProcessingDelegate;
- }
-
- internal TOutput Process(TInput input)
- {
- return stageDelegate(input);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/PacketPipelineBuilder.cs b/NetSharp/NetSharp/Deprecated/PacketPipelineBuilder.cs
@@ -1,87 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows for configuring and subsequently building a <see cref="PacketPipeline{TInput,TIntermediate,TOutput}"/> instance.
- /// </summary>
- /// <typeparam name="TInput">The type of packet that will be submitted to the pipeline.</typeparam>
- /// <typeparam name="TIntermediate">The type of packet that will be handled internally by the pipeline.</typeparam>
- /// <typeparam name="TOutput">The type of packet that will be requested from the pipeline.</typeparam>
- internal sealed class PacketPipelineBuilder<TInput, TIntermediate, TOutput>
- {
- private readonly List<PacketPipelineStage<TIntermediate, TIntermediate>> intermediateStages;
-
- private PacketPipelineStage<TInput, TIntermediate>? inputStage;
- private PacketPipelineStage<TIntermediate, TOutput>? outputStage;
-
- internal PacketPipelineBuilder()
- {
- intermediateStages = new List<PacketPipelineStage<TIntermediate, TIntermediate>>();
- }
-
- /// <summary>
- /// Returns the currently configured <see cref="PacketPipeline{TInput,TIntermediate,TOutput}"/> instance.
- /// </summary>
- /// <returns>The configured <see cref="PacketPipeline{TInput,TIntermediate,TOutput}"/> instance.</returns>
- /// <exception cref="ArgumentNullException">
- /// Thrown when either <see cref="WithInputStage"/> or <see cref="WithOutputStage"/> have not been called.
- /// </exception>
- internal PacketPipeline<TInput, TIntermediate, TOutput> Build()
- {
- if (inputStage == null)
- {
- throw new ArgumentNullException(nameof(inputStage), $"{nameof(WithInputStage)} has not been called.");
- }
-
- if (outputStage == null)
- {
- throw new ArgumentNullException(nameof(outputStage), $"{nameof(WithOutputStage)} has not been called.");
- }
-
- return new PacketPipeline<TInput, TIntermediate, TOutput>(inputStage.Value, outputStage.Value, intermediateStages);
- }
-
- /// <summary>
- /// Configures the input stage for the pipeline.
- /// </summary>
- /// <param name="stage">
- /// The transformation that should be applied to incoming packets, to convert them from the <typeparamref name="TInput"/>
- /// type to the <typeparamref name="TIntermediate"/> type that the pipeline handles internally.
- /// </param>
- /// <returns>The builder instance for further configuration.</returns>
- internal PacketPipelineBuilder<TInput, TIntermediate, TOutput> WithInputStage(in Func<TInput, TIntermediate> stage)
- {
- inputStage = new PacketPipelineStage<TInput, TIntermediate>(in stage);
- return this;
- }
-
- /// <summary>
- /// Adds the given intermediate stage to the pipeline.
- /// </summary>
- /// <param name="stage">
- /// The transformation that should be applied to packets traveling through the pipeline.
- /// </param>
- /// <returns>The builder instance for further configuration.</returns>
- internal PacketPipelineBuilder<TInput, TIntermediate, TOutput> WithIntermediateStage(in Func<TIntermediate, TIntermediate> stage)
- {
- intermediateStages.Add(new PacketPipelineStage<TIntermediate, TIntermediate>(in stage));
- return this;
- }
-
- /// <summary>
- /// Configures the output stage for the pipeline.
- /// </summary>
- /// <param name="stage">
- /// The transformation that should be applied to outgoing packets, to convert them from the
- /// <typeparamref name="TIntermediate"/> type used internally to the <typeparamref name="TOutput"/> type.
- /// </param>
- /// <returns>The builder instance for further configuration.</returns>
- internal PacketPipelineBuilder<TInput, TIntermediate, TOutput> WithOutputStage(in Func<TIntermediate, TOutput> stage)
- {
- outputStage = new PacketPipelineStage<TIntermediate, TOutput>(in stage);
- return this;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/PacketRegistry.cs b/NetSharp/NetSharp/Deprecated/PacketRegistry.cs
@@ -1,285 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides method of registering request packets and their relevant response packets, as well as mapping their ids.
- /// </summary>
- internal static class PacketRegistry
- {
- /// <summary>
- /// The start id for automatically generated packet type ids. Any custom packet type ids lower than this value
- /// that come from external assemblies will be incremented by this value, to ensure that there are no clashes.
- /// </summary>
- private const uint AutomaticPacketTypeIdStartPoint = 100;
-
- /// <summary>
- /// The lock object for synchronising access to the <see cref="currentAutomaticPacketTypeIdCounter"/> field.
- /// </summary>
- private static readonly object currentAutomaticPacketTypeIdCounterLockObject = new object();
-
- /// <summary>
- /// Maps a packet type id to its relevant packet type, and vice-versa.
- /// </summary>
- private static readonly BiDictionary<uint, Type> idToPacketTypeMap;
-
- /// <summary>
- /// The assembly that represents the library, where all of the builtin packets are defined.
- /// </summary>
- private static readonly Assembly LibraryAssembly = Assembly.GetAssembly(typeof(PacketRegistry));
-
- /// <summary>
- /// Maps a request packet to its relevant response packet, and vice-versa.
- /// </summary>
- private static readonly BiDictionary<Type, Type> requestToResponseMap;
-
- /// <summary>
- /// The current id for registered packets.
- /// </summary>
- private static uint currentAutomaticPacketTypeIdCounter = AutomaticPacketTypeIdStartPoint;
-
- /// <summary>
- /// Fetches the packet type id of the given packet type. If the packet type is declared outside of the library
- /// assembly, then its value is incremented by the <see cref="AutomaticPacketTypeIdStartPoint"/> value. This ensure that
- /// there are no clashes between the packet type ids of packets declared in the library and external packets.
- /// </summary>
- /// <param name="packetType">The packet type whose id should be fetched.</param>
- /// <returns>The id of the given packet type.</returns>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static uint GetNewPacketTypeId(Type packetType)
- {
- uint packetTypeId;
-
- if (packetType.Assembly != LibraryAssembly)
- {
- lock (currentAutomaticPacketTypeIdCounterLockObject)
- {
- packetTypeId = currentAutomaticPacketTypeIdCounter++;
- }
- }
- else
- {
- PacketTypeIdAttribute customPacketTypeIdAttribute =
- (PacketTypeIdAttribute)packetType.GetCustomAttributes(typeof(PacketTypeIdAttribute)).First();
-
- packetTypeId = customPacketTypeIdAttribute.Id;
- }
-
- return packetTypeId;
- }
-
- /// <summary>
- /// Deregisters the given packet type from the registry.
- /// </summary>
- /// <param name="requestPacketType">The request packet type to deregister, if it is registered.</param>
- /// <param name="responsePacketType">The response packet associated with the request packet.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void DeregisterPacketType(Type requestPacketType, Type? responsePacketType)
- {
- if (idToPacketTypeMap.ContainsValue(requestPacketType))
- {
- idToPacketTypeMap.TryClearKey(requestPacketType, out _);
- }
-
- // if the given response packet is null, then skip deregistering a response packet type
- if (responsePacketType == default) return;
-
- if (!idToPacketTypeMap.ContainsValue(responsePacketType))
- {
- idToPacketTypeMap.TryClearKey(responsePacketType, out _);
- }
-
- if (!requestToResponseMap.ContainsValue(requestPacketType))
- {
- requestToResponseMap.TryClearKey(requestPacketType, out _);
- }
- }
-
- /// <summary>
- /// Deregisters the given packet types from the registry.
- /// </summary>
- /// <param name="requestToResponsePacketTypeMap">The list of packet types to deregister, if they are registered.</param>
- internal static void DeregisterPacketTypes(Dictionary<Type, Type?> requestToResponsePacketTypeMap)
- {
- foreach ((Type requestPacketType, Type? responsePacketType) in requestToResponsePacketTypeMap)
- {
- DeregisterPacketType(requestPacketType, responsePacketType);
- }
- }
-
- /// <summary>
- /// Returns the packet type id associated with the given packet type.
- /// </summary>
- /// <param name="packetType">The packet type whose id to fetch.</param>
- /// <returns>The id of the packet type given.</returns>
- internal static uint GetPacketId(Type packetType) => idToPacketTypeMap[packetType];
-
- /// <summary>
- /// Returns the packet type id associated with the given packet type.
- /// </summary>
- /// <typeparam name="TPacket">The packet type whose id to fetch.</typeparam>
- /// <returns>The id of the packet type given.</returns>
- internal static uint GetPacketId<TPacket>() where TPacket : IPacket => idToPacketTypeMap[typeof(TPacket)];
-
- /// <summary>
- /// Returns the packet type associated with the given id.
- /// </summary>
- /// <param name="packetTypeId">The packet id whose mapped type to fetch.</param>
- /// <returns>The packet type mapped by the given id.</returns>
- internal static Type GetPacketType(uint packetTypeId) => idToPacketTypeMap[packetTypeId];
-
- /// <summary>
- /// Returns the type of request packet mapped by the given response packet type.
- /// </summary>
- /// <typeparam name="TResponse">The response packet type whose request packet type to fetch.</typeparam>
- /// <returns>The request packet type, <c>null</c> if no type is mapped.</returns>
- internal static Type GetRequestPacketType<TResponse>() where TResponse : IResponsePacket<IRequestPacket>
- {
- requestToResponseMap.TryGetKey(typeof(TResponse), out Type requestPacketType);
-
- return requestPacketType;
- }
-
- /// <summary>
- /// Returns the type of request packet mapped by the given response packet type.
- /// </summary>
- /// <param name="responsePacketType">The response packet type whose request packet type to fetch.</param>
- /// <returns>The request packet type, <c>null</c> if no type is mapped.</returns>
- internal static Type GetRequestPacketType(Type responsePacketType)
- {
- requestToResponseMap.TryGetKey(responsePacketType, out Type requestPacketType);
-
- return requestPacketType;
- }
-
- /// <summary>
- /// Returns the type of response packet mapped by the given request packet type.
- /// </summary>
- /// <typeparam name="TRequest">The request packet type whose response packet type to fetch.</typeparam>
- /// <returns>The response packet type, <c>null</c> if no type is mapped.</returns>
- internal static Type? GetResponsePacketType<TRequest>() where TRequest : IRequestPacket
- {
- return requestToResponseMap.TryGetValue(typeof(TRequest), out Type responsePacketType) ? responsePacketType : default;
- }
-
- /// <summary>
- /// Returns the type of response packet mapped by the given request packet type.
- /// </summary>
- /// <param name="requestPacketType">The request packet type whose response packet type to fetch.</param>
- /// <returns>The response packet type, <c>null</c> if no type is mapped.</returns>
- internal static Type? GetResponsePacketType(Type requestPacketType)
- {
- return requestToResponseMap.TryGetValue(requestPacketType, out Type responsePacketType) ? responsePacketType : default;
- }
-
- /// <summary>
- /// Rebuilds the packet registry, by registering every <see cref="IPacket"/> inheritor in the given assemblies.
- /// </summary>
- /// <param name="packetSourceAssemblies">
- /// The assemblies from which the packet types to register are sourced.
- /// </param>
- internal static void RegisterPacketSourceAssemblies(params Assembly[] packetSourceAssemblies)
- {
- foreach (Assembly assembly in packetSourceAssemblies)
- {
- RegisterPacketSourceAssembly(assembly);
- }
- }
-
- /// <summary>
- /// Registers all the <see cref="IPacket"/> implementors in the given assembly.
- /// </summary>
- /// <param name="packetSourceAssembly">The assembly whose packet types to register.</param>
- //[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void RegisterPacketSourceAssembly(Assembly packetSourceAssembly)
- {
- Dictionary<Type, Type?> requestToResponseTypeMap = new Dictionary<Type, Type?>();
-
- foreach (Type type in packetSourceAssembly.DefinedTypes)
- {
- foreach (Type interfaceType in type.GetInterfaces())
- {
- if (!typeof(IPacket).IsAssignableFrom(interfaceType) || interfaceType == typeof(IPacket))
- {
- continue;
- }
-
- if (interfaceType == typeof(IRequestPacket))
- {
- requestToResponseTypeMap[type] = default;
- }
- else //if (interfaceType == typeof(IResponsePacket<>))
- {
- Type handledRequestType = interfaceType.GetGenericArguments()[0];
-
- requestToResponseTypeMap[handledRequestType] = type;
- }
- }
- }
-
- RegisterPacketTypes(requestToResponseTypeMap);
- }
-
- /// <summary>
- /// Registers the given packet type to the registry.
- /// </summary>
- /// <param name="requestPacketType">The request packet type to register, if it is not registered.</param>
- /// <param name="responsePacketType">The response packet associated with the request packet.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void RegisterPacketType(Type requestPacketType, Type? responsePacketType)
- {
- if (!idToPacketTypeMap.ContainsValue(requestPacketType))
- {
- uint requestPacketTypeId = GetNewPacketTypeId(requestPacketType);
-
- idToPacketTypeMap.TrySetValue(requestPacketTypeId, requestPacketType);
- }
-
- // if the given response packet is null, then skip registering a response packet type
- if (responsePacketType == default) return;
-
- if (!idToPacketTypeMap.ContainsValue(responsePacketType))
- {
- uint responsePacketTypeId = GetNewPacketTypeId(responsePacketType);
-
- idToPacketTypeMap.TrySetValue(responsePacketTypeId, responsePacketType);
- }
-
- if (!requestToResponseMap.ContainsValue(requestPacketType))
- {
- requestToResponseMap.TrySetValue(requestPacketType, responsePacketType);
- }
- }
-
- /// <summary>
- /// Registers the given packet types to the registry.
- /// </summary>
- /// <param name="requestToResponsePacketTypeMap">
- /// The dictionary mapping the request packet types to register, to their relevant response packet types.
- /// The response packet type can be null; then the request packet type is treated as a 'simple' packet.
- /// </param>
- internal static void RegisterPacketTypes(Dictionary<Type, Type?> requestToResponsePacketTypeMap)
- {
- foreach ((Type requestPacketType, Type? responsePacketType) in requestToResponsePacketTypeMap)
- {
- RegisterPacketType(requestPacketType, responsePacketType);
- }
- }
-
- /// <summary>
- /// Initialises a new instance of the <see cref="PacketRegistry"/> class.
- /// </summary>
- static PacketRegistry()
- {
- idToPacketTypeMap = new BiDictionary<uint, Type>();
-
- requestToResponseMap = new BiDictionary<Type, Type>();
-
- RegisterPacketSourceAssembly(LibraryAssembly);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/PacketTypeIdAttribute.cs b/NetSharp/NetSharp/Deprecated/PacketTypeIdAttribute.cs
@@ -1,26 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows the placing of a custom packet type on a class or struct. This is used if the class or struct
- /// inherits from <see cref="IRequestPacket"/> or <see cref="IResponsePacket{TReq}"/>.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
- internal sealed class PacketTypeIdAttribute : Attribute
- {
- /// <summary>
- /// Initialises a new instance of the <see cref="PacketTypeIdAttribute"/> attribute.
- /// </summary>
- /// <param name="type">The custom type id that the decorated packet type should have.</param>
- internal PacketTypeIdAttribute(uint type)
- {
- Id = type;
- }
-
- /// <summary>
- /// The custom type id that the decorated packet type should have. This overrides the automatically generated id.
- /// </summary>
- internal uint Id { get; }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/RemoteSocketClient.cs b/NetSharp/NetSharp/Deprecated/RemoteSocketClient.cs
@@ -1,73 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using NetSharp.Utils;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- public class RemoteSocketClient : IDisposable
- {
- private readonly ObjectPool<SocketAsyncEventArgs> transmissionArgsPool;
-
- protected readonly Socket transmitterSocket;
-
- internal RemoteSocketClient(Socket clientSocket)
- {
- transmitterSocket = clientSocket;
-
- transmissionArgsPool = new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>());
- }
-
- /// <inheritdoc />
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Implementation of dispose pattern.
- /// </summary>
- /// <param name="disposing">
- /// Whether this method is being called by the object finalizer, or by the <see cref="Dispose()"/> method.
- /// </param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- transmitterSocket.Dispose();
- }
- }
-
- public async ValueTask<TransmissionResult> ReceiveAsync(EndPoint remoteEndPoint, SocketFlags receiveFlags, Memory<byte> receiveBuffer,
- CancellationToken cancellationToken = default)
- {
- SocketAsyncEventArgs transmissionArgs = transmissionArgsPool.Get();
-
- TransmissionResult receiveResult = await SocketOperations.ReceiveFromAsync(transmissionArgs, transmitterSocket,
- remoteEndPoint, receiveFlags, receiveBuffer, cancellationToken);
-
- transmissionArgsPool.Return(transmissionArgs);
-
- return receiveResult;
- }
-
- public async ValueTask<TransmissionResult> SendAsync(EndPoint remoteEndPoint, SocketFlags sendFlags, Memory<byte> sendBuffer,
- CancellationToken cancellationToken = default)
- {
- SocketAsyncEventArgs transmissionArgs = transmissionArgsPool.Get();
-
- TransmissionResult sendResult = await SocketOperations.SendToAsync(transmissionArgs, transmitterSocket,
- remoteEndPoint, sendFlags, sendBuffer, cancellationToken);
-
- transmissionArgsPool.Return(transmissionArgs);
-
- return sendResult;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/RingBuffer.cs b/NetSharp/NetSharp/Deprecated/RingBuffer.cs
@@ -1,48 +0,0 @@
-namespace NetSharp.Deprecated
-{
- public class RingBuffer<T>
- {
- private readonly T[] buffer;
-
- private int currentIndex;
-
- public RingBuffer(int capacity)
- {
- buffer = new T[capacity];
-
- Capacity = capacity;
- Count = 0;
- }
-
- public int Capacity { get; }
-
- public int Count { get; }
-
- public T Pop()
- {
- T removedItem = buffer[currentIndex--];
-
- currentIndex = currentIndex < 0 ? currentIndex + Capacity : currentIndex;
-
- return removedItem;
- }
-
- public bool Push(T newItem, out T removedItem)
- {
- bool overwroteItem = false;
- removedItem = default;
-
- if (buffer[currentIndex] != null)
- {
- removedItem = buffer[currentIndex];
- overwroteItem = true;
- }
-
- buffer[currentIndex] = newItem;
-
- currentIndex = (currentIndex + 1) % Capacity;
-
- return overwroteItem;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SerialisedPacket.cs b/NetSharp/NetSharp/Deprecated/SerialisedPacket.cs
@@ -1,47 +0,0 @@
-using System;
-
-namespace NetSharp.Deprecated
-{
- public readonly struct SerialisedPacket
- {
- public static readonly SerialisedPacket Null = new SerialisedPacket(Memory<byte>.Empty, 0);
- public readonly Memory<byte> Contents;
- public readonly uint Type;
-
- public SerialisedPacket(Memory<byte> contents, uint type)
- {
- Contents = contents;
-
- Type = type;
- }
-
- /// <summary>
- /// Serialises the given serialisable packet instance and returns the <see cref="SerialisedPacket"/> instance
- /// that was generated. This method invokes <see cref="IPacket.BeforeSerialisation"/>.
- /// </summary>
- /// <typeparam name="T">The packet type that will be serialised.</typeparam>
- /// <param name="serialisable">The packet instance that should be serialised.</param>
- /// <returns>The serialised instance.</returns>
- public static SerialisedPacket From<T>(T serialisable) where T : class, IPacket, INetworkSerialisable
- {
- serialisable.BeforeSerialisation();
- return new SerialisedPacket(serialisable.Serialise(), PacketRegistry.GetPacketId<T>());
- }
-
- /// <summary>
- /// Deserialises and returns a packet instance of the given type from the <see cref="SerialisedPacket"/> instance
- /// that was given. This method invokes <see cref="IPacket.AfterDeserialisation"/>.
- /// </summary>
- /// <typeparam name="T">The packet type to which the packet should be deserialised.</typeparam>
- /// <param name="instance">The serialised packet instance that should be deserialised.</param>
- /// <returns>The deserialised instance.</returns>
- public static T To<T>(in SerialisedPacket instance) where T : class, IPacket, INetworkSerialisable, new()
- {
- T packet = new T();
- packet.Deserialise(instance.Contents);
- packet.AfterDeserialisation();
-
- return packet;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/Server.cs b/NetSharp/NetSharp/Deprecated/Server.cs
@@ -1,593 +0,0 @@
-using NetSharp.Deprecated.Builtin;
-
-using System;
-using System.Collections.Concurrent;
-using System.Net;
-using System.Net.Sockets;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Represents a method that receives a request packet of the given type (<typeparamref name="TReq"/>) and
- /// handles the request, returning a response packet of the given type (<typeparamref name="TRep"/>).
- /// </summary>
- /// <typeparam name="TReq">The type of request packet handled by this delegate method.</typeparam>
- /// <typeparam name="TRep">The type of response packet returned by this delegate method.</typeparam>
- /// <param name="requestPacket">The request packet that should be handled by this delegate method.</param>
- /// <param name="remoteEndPoint">The remote endpoint from which the request originated.</param>
- /// <returns>The response packet to send back to the remote endpoint from which the request originated.</returns>
- public delegate TRep ComplexPacketHandler<in TReq, out TRep>(TReq requestPacket, EndPoint remoteEndPoint)
- where TReq : class, IRequestPacket, new() where TRep : class, IResponsePacket<TReq>, new();
-
- /// <summary>
- /// Represents a method that receives a simple request packet of the given type (<typeparamref name="TReq"/>) and
- /// handles the request, not returning any response packets.
- /// </summary>
- /// <typeparam name="TReq">The type of request packet handled by this delegate method.</typeparam>
- /// <param name="requestPacket">The request packet that should be handled by this delegate method.</param>
- /// <param name="remoteEndPoint">The remote endpoint from which the request originated.</param>
- public delegate void SimplePacketHandler<in TReq>(TReq requestPacket, EndPoint remoteEndPoint)
- where TReq : class, IRequestPacket, new();
-
- /// <summary>
- /// Provides methods for handling connected <see cref="IClient"/> instances.
- /// </summary>
- public abstract class Server : ServerClientConnection, IServer, IPacketHandler, IDisposable
- {
- /// <summary>
- /// Maps a packet type id to the complex packet handler for that packet type.
- /// </summary>
- private readonly ConcurrentDictionary<uint, Func<IRequestPacket, EndPoint, IResponsePacket<IRequestPacket>>>
- complexPacketHandlers;
-
- /// <summary>
- /// Maps a packet type id to the raw packet deserialiser that deserialises raw packets to
- /// <see cref="IRequestPacket"/> implementors.
- /// </summary>
- private readonly ConcurrentDictionary<uint, RawRequestPacketDeserialiser> requestPacketDeserialisers;
-
- /// <summary>
- /// Cancellation token source to stop handling client sockets when the server should be shut down.
- /// </summary>
- private readonly CancellationTokenSource serverShutdownCancellationTokenSource;
-
- /// <summary>
- /// Maps a packet type id to the simple packet handler for that packet type.
- /// </summary>
- private readonly ConcurrentDictionary<uint, Action<IRequestPacket, EndPoint>> simplePacketHandlers;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="Server"/> class.
- /// </summary>
- private Server()
- {
- serverShutdownCancellationTokenSource = new CancellationTokenSource();
-
- serverShutdownCancellationToken = serverShutdownCancellationTokenSource.Token;
-
- requestPacketDeserialisers = new ConcurrentDictionary<uint, RawRequestPacketDeserialiser>();
-
- simplePacketHandlers = new ConcurrentDictionary<uint, Action<IRequestPacket, EndPoint>>();
- complexPacketHandlers =
- new ConcurrentDictionary<uint, Func<IRequestPacket, EndPoint, IResponsePacket<IRequestPacket>>>();
-
- RegisterInternalPacketHandlers();
-
- socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- socketOptions = new DefaultSocketOptions(ref socket);
- }
-
- /// <summary>
- /// Destroys an instance of the <see cref="Server"/> class.
- /// </summary>
- ~Server()
- {
- Dispose(false);
- }
-
- /// <summary>
- /// Represents a method that receives a raw packet, and deserialises it into an <see cref="IRequestPacket"/> implementor.
- /// </summary>
- /// <param name="rawPacket">The raw packet that was received from the network.</param>
- /// <returns>The deserialised instance of the packet.</returns>
- private delegate IRequestPacket RawRequestPacketDeserialiser(in SerialisedPacket rawPacket);
-
- /// <summary>
- /// Registers packet handlers for every internal library packet.
- /// </summary>
- private void RegisterInternalPacketHandlers()
- {
- TryRegisterSimplePacketHandler((DisconnectPacket packet, EndPoint remoteEndPoint) =>
- {
-#if DEBUG
- logger.LogMessage($"Received disconnect packet from {remoteEndPoint}");
-#endif
- OnClientDisconnected(remoteEndPoint);
- });
-
- TryRegisterSimplePacketHandler((SimpleDataPacket packet, EndPoint remoteEndPoint) =>
- {
-#if DEBUG
- logger.LogMessage($"Received {packet.RequestBuffer.Length} bytes from {remoteEndPoint}");
-#endif
- });
-
- TryRegisterComplexPacketHandler((ConnectPacket packet, EndPoint remoteEndPoint) =>
- {
- OnClientConnected(remoteEndPoint);
-#if DEBUG
- logger.LogMessage($"Received connection request from {remoteEndPoint}");
-#endif
- return new ConnectResponsePacket { RequestPacket = packet };
- });
-
- TryRegisterComplexPacketHandler((PingPacket packet, EndPoint remoteEndPoint) =>
- new PingResponsePacket { RequestPacket = packet });
-
- TryRegisterComplexPacketHandler((DataPacket packet, EndPoint remoteEndPoint) =>
- {
-#if DEBUG
- logger.LogMessage($"Received {packet.RequestBuffer.Length} bytes from {remoteEndPoint}");
- logger.LogMessage($"Sending {packet.RequestBuffer.Length} bytes to {remoteEndPoint}");
-#endif
- return new DataResponsePacket { RequestPacket = packet, ResponseBuffer = packet.RequestBuffer };
- });
- }
-
- /// <summary>
- /// The maximum number of connections that are allowed in the connection backlog.
- /// </summary>
- protected const int PendingConnectionBacklog = 100;
-
- /// <summary>
- /// The default timeout value for all network operations.
- /// </summary>
- protected static readonly TimeSpan DefaultNetworkOperationTimeout = TimeSpan.FromMilliseconds(10_000);
-
- /// <summary>
- /// The cancellation token that will be set when the server must be shut down.
- /// </summary>
- protected readonly CancellationToken serverShutdownCancellationToken;
-
- /// <summary>
- /// The <see cref="Socket"/> underlying the connection.
- /// </summary>
- protected readonly Socket socket;
-
- /// <summary>
- /// Backing field for the <see cref="SocketOptions"/> property.
- /// </summary>
- protected readonly SocketOptions socketOptions;
-
- /// <summary>
- /// Whether the server should be ran.
- /// </summary>
- protected volatile bool runServer;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="Server"/> class.
- /// </summary>
- /// <param name="socketType">The socket type for the underlying socket.</param>
- /// <param name="protocolType">The protocol type for the underlying socket.</param>
- /// <param name="socketManager">The <see cref="Utils.Socket_Options.SocketOptions"/> implementation to use.</param>
- protected Server(SocketType socketType, ProtocolType protocolType)
- : this(socketType, protocolType, DefaultNetworkOperationTimeout)
- {
- }
-
- /// <summary>
- /// Initialises a new instance of the <see cref="Server"/> class.
- /// </summary>
- /// <param name="socketType">The socket type for the underlying socket.</param>
- /// <param name="protocolType">The protocol type for the underlying socket.</param>
- /// <param name="socketManager">The <see cref="Utils.Socket_Options.SocketOptions"/> manager to use.</param>
- /// <param name="networkOperationTimeout">The timeout value for send and receive operations over the network.</param>
- protected Server(SocketType socketType, ProtocolType protocolType, TimeSpan networkOperationTimeout) : this()
- {
- socket = new Socket(AddressFamily.InterNetwork, socketType, protocolType);
-
- socketOptions = new DefaultSocketOptions(ref socket);
-
- NetworkOperationTimeout = networkOperationTimeout;
- }
-
- /// <summary>
- /// Deserialises the given <see cref="NetworkPacket"/> struct into an <see cref="IRequestPacket"/> implementor.
- /// </summary>
- /// <param name="packetType">The type id of packet that we should deserialise to.</param>
- /// <param name="rawRequestPacket">The packet that should be deserialised.</param>
- /// <returns>The deserialised packet instance, cast to the <see cref="IRequestPacket"/> interface.</returns>
- protected IRequestPacket? DeserialiseRequestPacket(uint packetType, in SerialisedPacket rawRequestPacket)
- {
- if (requestPacketDeserialisers.TryGetValue(packetType, out RawRequestPacketDeserialiser deserialiser))
- {
- return deserialiser.Invoke(rawRequestPacket);
- }
-#if DEBUG
- logger.LogWarning($"No packet deserialiser was registered for packet of type {packetType}");
-#endif
- return default;
- }
-
- /// <summary>
- /// Disposes of this <see cref="Server"/> instance.
- /// </summary>
- /// <param name="disposing">Whether this instance is being disposed.</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- serverShutdownCancellationTokenSource?.Cancel();
- serverShutdownCancellationTokenSource?.Dispose();
-
- socket.Dispose();
- }
-
- base.Dispose(disposing);
- }
-
- /// <summary>
- /// Provides a task that represents the handling of a client. Calls the abstract <see cref="HandleClientAsync"/> method.
- /// </summary>
- /// <param name="clientHandlerArgsObj">The object representing the passed <see cref="ClientHandlerArgs"/> instance.</param>
- protected async Task DoHandleClientAsync(object clientHandlerArgsObj)
- {
- ClientHandlerArgs clientHandlerArgs = (ClientHandlerArgs)clientHandlerArgsObj;
-
- try
- {
- await HandleClientAsync(clientHandlerArgs, serverShutdownCancellationTokenSource.Token);
- }
- catch (TaskCanceledException)
- {
- logger.LogWarning("Client handling was cancelled via a task cancellation.");
- }
- catch (OperationCanceledException)
- {
- logger.LogWarning("Client handling was cancelled via an operation cancellation.");
- }
- catch (Exception ex)
- {
- logger.LogException("Exception during client handling", ex);
- }
- finally
- {
- if (clientHandlerArgs.ClientSocket != null)
- {
- logger.LogMessage("Closing and releasing all resources associated with client handler socket");
-
- clientHandlerArgs.ClientSocket.Shutdown(SocketShutdown.Both);
- clientHandlerArgs.ClientSocket.Disconnect(true);
- clientHandlerArgs.ClientSocket.Close(1);
- clientHandlerArgs.ClientSocket.Dispose();
- }
- }
- }
-
- /// <summary>
- /// Handles a client asynchronously.
- /// </summary>
- /// <param name="args">The client handler arguments that should be passed to the client handler.</param>
- /// <param name="cancellationToken">Cancellation token set when the server is shutting down.</param>
- protected abstract Task HandleClientAsync(ClientHandlerArgs args, CancellationToken cancellationToken);
-
- /// <summary>
- /// Handles the given request packet with a registered packet handler. In this case, a complex packet handler
- /// will override any registered simple packet handlers.
- /// </summary>
- /// <param name="packetType">The type id of the packet that we should handle.</param>
- /// <param name="requestPacket">The packet instance that should be handled.</param>
- /// <param name="remoteEndPoint">The remote endpoint from which the request packet originated.</param>
- /// <returns>The response packet that should be sent back to the remote endpoint.</returns>
- protected IResponsePacket<IRequestPacket>? HandleRequestPacket(uint packetType, in IRequestPacket requestPacket,
- in EndPoint remoteEndPoint)
- {
- try
- {
- if (complexPacketHandlers.ContainsKey(packetType))
- {
- IResponsePacket<IRequestPacket> response =
- complexPacketHandlers[packetType].Invoke(requestPacket, remoteEndPoint);
-
- return response;
- }
-
- if (simplePacketHandlers.ContainsKey(packetType))
- {
- simplePacketHandlers[packetType].Invoke(requestPacket, remoteEndPoint);
- return null;
- }
-
-#if DEBUG
- logger.LogWarning($"No packet handler was registered for packet of type {packetType}");
-#endif
- }
- catch (Exception ex)
- {
- logger.LogException(
- $"Exception when invoking packet handler for packet (type: {packetType}) received from {remoteEndPoint}",
- ex);
- }
-
- return default;
- }
-
- /// <summary>
- /// Invokes the <see cref="ClientConnected"/> event.
- /// </summary>
- /// <param name="remoteEndPoint">The remote endpoint with which a connection was made.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnClientConnected(EndPoint remoteEndPoint) => ClientConnected?.Invoke(remoteEndPoint);
-
- /// <summary>
- /// Invokes the <see cref="ClientDisconnected"/> event.
- /// </summary>
- /// <param name="remoteEndPoint">The remote endpoint with which a connection was lost.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnClientDisconnected(EndPoint remoteEndPoint) => ClientDisconnected?.Invoke(remoteEndPoint);
-
- /// <summary>
- /// Invokes the <see cref="ServerStarted"/> event.
- /// </summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnServerStarted() => ServerStarted?.Invoke();
-
- /// <summary>
- /// Invokes the <see cref="ServerStopped"/> event.
- /// </summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnServerStopped() => ServerStopped?.Invoke();
-
- /// <summary>
- /// Attempts to synchronously bind the underlying socket to the given local endpoint. Blocks.
- /// If the timeout is exceeded the binding attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="localEndPoint">The local endpoint to bind to.</param>
- /// <param name="timeout">The timeout within which to attempt the binding.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- protected bool TryBind(EndPoint localEndPoint, TimeSpan timeout) =>
- TryBindAsync(localEndPoint, timeout).Result;
-
- /// <summary>
- /// Attempts to asynchronously bind the underlying socket to the given local endpoint. Does not block.
- /// If the timeout is exceeded the binding attempt is aborted and the method returns false.
- /// </summary>
- /// <param name="localEndPoint">The local endpoint to bind to.</param>
- /// <param name="timeout">The timeout within which to attempt the binding.</param>
- /// <returns>Whether the binding was successful or not.</returns>
- protected async Task<bool> TryBindAsync(EndPoint localEndPoint, TimeSpan timeout)
- {
- using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource(timeout);
- using CancellationTokenSource cts =
- CancellationTokenSource.CreateLinkedTokenSource(timeoutCancellationTokenSource.Token, serverShutdownCancellationToken);
-
- try
- {
- return await Task.Run(() =>
- {
- socket.Bind(localEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return false;
- }
- catch (SocketException ex)
- {
- logger.LogException($"Socket exception on binding socket to {localEndPoint}:", ex);
- return false;
- }
- }
-
- /// <summary>
- /// Holds information about the arguments passed to every client handler task.
- /// </summary>
- protected readonly struct ClientHandlerArgs
- {
- /// <summary>
- /// Initialises a new instance of the <see cref="ClientHandlerArgs"/> struct.
- /// </summary>
- /// <param name="remoteEndPoint">The remote endpoint of the client that should be handled.</param>
- /// <param name="handlerSocket">The handler socket of the client that should be handled.</param>
- private ClientHandlerArgs(EndPoint remoteEndPoint, Socket? handlerSocket)
- {
- ClientEndPoint = remoteEndPoint;
-
- ClientSocket = handlerSocket;
- }
-
- /// <summary>
- /// The remote endpoint for the client being handled.
- /// </summary>
- public readonly EndPoint ClientEndPoint;
-
- /// <summary>
- /// The client handler socket for the client being handled. Is only set if using TCP.
- /// </summary>
- public readonly Socket? ClientSocket;
-
- /// <summary>
- /// Constructs a new instance of the <see cref="ClientHandlerArgs"/> for a TCP client.
- /// </summary>
- /// <returns>A new instance of the <see cref="ClientHandlerArgs"/>, setup for a TCP client.</returns>
- public static ClientHandlerArgs ForTcpClientHandler(in Socket clientHandlerSocket)
- {
- return new ClientHandlerArgs(clientHandlerSocket.RemoteEndPoint, clientHandlerSocket);
- }
-
- /// <summary>
- /// Constructs a new instance of the <see cref="ClientHandlerArgs"/> for a UDP client.
- /// </summary>
- /// <returns>A new instance of the <see cref="ClientHandlerArgs"/>, setup for a UDP client.</returns>
- public static ClientHandlerArgs ForUdpClientHandler(in EndPoint clientEndPoint)
- {
- return new ClientHandlerArgs(clientEndPoint, null);
- }
- }
-
- /// <summary>
- /// Signifies that a connection with a remote endpoint has been made.
- /// </summary>
- public event Action<EndPoint>? ClientConnected;
-
- //protected IResponsePacket<IRequestPacket> DeserialiseResponsePacket(in Packet)
- /// <summary>
- /// Signifies that a connection with a remote endpoint has been lost.
- /// </summary>
- public event Action<EndPoint>? ClientDisconnected;
-
- /// <summary>
- /// Signifies that the server was started and clients will start being accepted.
- /// </summary>
- public event Action? ServerStarted;
-
- /// <summary>
- /// Signifies that the server was stopped and clients will stop being accepted.
- /// </summary>
- public event Action? ServerStopped;
-
- /// <summary>
- /// The timeout value for network operations such as sending bytes or receiving bytes over the network.
- /// </summary>
- public TimeSpan NetworkOperationTimeout { get; protected set; }
-
- /// <summary>
- /// The configured socket options for the underlying connection.
- /// </summary>
- public SocketOptions SocketOptions
- {
- get { return socketOptions; }
- }
-
- /// <inheritdoc />
- public abstract Task RunAsync(EndPoint localEndPoint);
-
- /// <inheritdoc />
- public void Shutdown()
- {
- runServer = false;
- logger.LogMessage("Signalling server shutdown to all client handlers...");
- serverShutdownCancellationTokenSource.Cancel();
- }
-
- /// <inheritdoc />
- public bool TryDeregisterComplexPacketHandler<Req, Rep>(out ComplexPacketHandler<Req, Rep>? oldHandlerDelegate)
- where Req : class, IRequestPacket, new() where Rep : class, IResponsePacket<Req>, new()
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
- oldHandlerDelegate = default;
-
- try
- {
- requestPacketDeserialisers.TryRemove(packetTypeId, out _);
-
- if (!complexPacketHandlers.TryGetValue(packetTypeId,
- out Func<IRequestPacket, EndPoint, IResponsePacket<IRequestPacket>> oldDelegate))
- return false;
-
- oldHandlerDelegate = (p, ep) => (Rep)oldDelegate(p, ep);
- return true;
- }
- catch (Exception ex)
- {
- logger.LogException("Exception when deregistering complex packet handler", ex);
- }
-
- return false;
- }
-
- /// <inheritdoc />
- public bool TryDeregisterSimplePacketHandler<Req>(out SimplePacketHandler<Req>? oldHandlerDelegate)
- where Req : class, IRequestPacket, new()
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
- oldHandlerDelegate = default;
-
- try
- {
- requestPacketDeserialisers.TryRemove(packetTypeId, out _);
-
- if (!simplePacketHandlers.TryGetValue(packetTypeId, out Action<IRequestPacket, EndPoint> oldDelegate))
- return false;
-
- oldHandlerDelegate = (p, ep) => oldDelegate(p, ep);
- return true;
- }
- catch (Exception ex)
- {
- logger.LogException("Exception when deregistering simple packet handler", ex);
- }
-
- return false;
- }
-
- /// <inheritdoc />
- public bool TryRegisterComplexPacketHandler<Req, Rep>(ComplexPacketHandler<Req, Rep> handlerDelegate)
- where Req : class, IRequestPacket, new() where Rep : class, IResponsePacket<Req>, new()
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
-
- static IRequestPacket PacketDeserialiser(in SerialisedPacket packet) => SerialisedPacket.To<Req>(packet);
-
- IResponsePacket<IRequestPacket> MappedHandlerDelegate(IRequestPacket p, EndPoint ep)
- {
- Rep responsePacket = handlerDelegate((Req)p, ep);
- return responsePacket;
- }
-
- try
- {
- requestPacketDeserialisers.AddOrUpdate(packetTypeId,
- key => PacketDeserialiser,
- (key, oldDeserialiser) => PacketDeserialiser);
-
- complexPacketHandlers.AddOrUpdate(packetTypeId,
- key => MappedHandlerDelegate,
- (key, oldDelegate) => MappedHandlerDelegate);
-
- return true;
- }
- catch (Exception ex)
- {
- logger.LogException("Exception when registering complex packet handler", ex);
- }
-
- return false;
- }
-
- /// <inheritdoc />
- public bool TryRegisterSimplePacketHandler<Req>(SimplePacketHandler<Req> handlerDelegate)
- where Req : class, IRequestPacket, new()
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
-
- static IRequestPacket PacketDeserialiser(in SerialisedPacket packet) => SerialisedPacket.To<Req>(packet);
-
- void MappedHandlerDelegate(IRequestPacket p, EndPoint ep) => handlerDelegate((Req)p, ep);
-
- try
- {
- requestPacketDeserialisers.AddOrUpdate(packetTypeId,
- key => PacketDeserialiser,
- (key, oldDeserialiser) => PacketDeserialiser);
-
- simplePacketHandlers.AddOrUpdate(packetTypeId,
- key => MappedHandlerDelegate,
- (key, oldDelegate) => MappedHandlerDelegate);
-
- return true;
- }
- catch (Exception ex)
- {
- logger.LogException("Exception when registering simple packet handler", ex);
- }
-
- return false;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ServerClientConnection.cs b/NetSharp/NetSharp/Deprecated/ServerClientConnection.cs
@@ -1,87 +0,0 @@
-using System;
-using System.IO;
-using System.Net;
-using System.Runtime.CompilerServices;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Base class for connections, holding methods shared between the <see cref="Client"/> and <see cref="Server"/> classes.
- /// </summary>
- public abstract class ServerClientConnection : IDisposable
- {
- /// <summary>
- /// The logger to which the server can log messages.
- /// </summary>
- protected Logger logger;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="ServerClientConnection"/> class.
- /// </summary>
- protected ServerClientConnection()
- {
- //networkManager = new NetworkOperationsManager();
-
- logger = new Logger(Stream.Null);
- }
-
- /// <summary>
- /// Disposes of this <see cref="ServerClientConnection"/> instance.
- /// </summary>
- /// <param name="disposing">Whether this instance is being disposed.</param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- logger.Dispose();
- }
- }
-
- /// <summary>
- /// Invokes the <see cref="BytesReceived"/> event.
- /// </summary>
- /// <param name="remoteEndPoint">The remote endpoint from which the bytes were received.</param>
- /// <param name="bytesReceived">The number of bytes that were received from the remote endpoint.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnBytesReceived(EndPoint remoteEndPoint, int bytesReceived) =>
- BytesReceived?.Invoke(remoteEndPoint, bytesReceived);
-
- /// <summary>
- /// Invokes the <see cref="BytesSent"/> event.
- /// </summary>
- /// <param name="remoteEndPoint">The remote endpoint to which the bytes were sent.</param>
- /// <param name="bytesSent">The number of bytes that were sent to the remote endpoint.</param>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected void OnBytesSent(EndPoint remoteEndPoint, int bytesSent) =>
- BytesSent?.Invoke(remoteEndPoint, bytesSent);
-
- /// <summary>
- /// Signifies that some data has been received from the remote endpoint.
- /// </summary>
- public event Action<EndPoint, int>? BytesReceived;
-
- /// <summary>
- /// Signifies that some data was sent to the remote endpoint.
- /// </summary>
- public event Action<EndPoint, int>? BytesSent;
-
- /// <summary>
- /// Makes the client log to the given stream.
- /// </summary>
- /// <param name="loggingStream">The stream that new messages should be logged to.</param>
- /// <param name="minimumMessageSeverityLevel">
- /// The minimum severity level that new messages must have to be logged to the stream.
- /// </param>
- public void ChangeLoggingStream(Stream loggingStream, LogLevel minimumMessageSeverityLevel = LogLevel.Info)
- {
- logger = new Logger(loggingStream, minimumMessageSeverityLevel);
- }
-
- /// <inheritdoc />
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/ServerExtensions.cs b/NetSharp/NetSharp/Deprecated/ServerExtensions.cs
@@ -1,46 +0,0 @@
-using System.Net;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides additional methods and functionality to the <see cref="Server"/> class.
- /// </summary>
- public static class ServerExtensions
- {
- /// <summary>
- /// Starts the server synchronously and starts accepting client connections. Blocks.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to.</param>
- /// <param name="localPort">The local port to bind to.</param>
- public static void Run(this Server instance, IPAddress localAddress, int localPort) =>
- instance.RunAsync(localAddress, localPort).Wait();
-
- /// <summary>
- /// Starts the server synchronously and starts accepting client connections. Blocks. Uses the default connection port.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to.</param>
- public static void Run(this Server instance, IPAddress localAddress) =>
- instance.RunAsync(localAddress, Constants.DefaultPort).Wait();
-
- /// <summary>
- /// Starts the server asynchronously and starts accepting client connections. Does not block. Uses the default
- /// connection port.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to.</param>
- public static async Task RunAsync(this Server instance, IPAddress localAddress) =>
- await instance.RunAsync(localAddress, Constants.DefaultPort);
-
- /// <summary>
- /// Starts the server asynchronously and starts accepting client connections. Does not block.
- /// </summary>
- /// <param name="instance">The instance on which this extension method should be called.</param>
- /// <param name="localAddress">The local IP address to bind to.</param>
- /// <param name="localPort">The local port to bind to.</param>
- public static async Task RunAsync(this Server instance, IPAddress localAddress, int localPort) =>
- await instance.RunAsync(new IPEndPoint(localAddress, localPort));
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketAcceptor.cs b/NetSharp/NetSharp/Deprecated/SocketAcceptor.cs
@@ -1,281 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Helper class providing awaitable wrappers around asynchronous Accept, Connect, and Disconnect operations.
- /// </summary>
- public sealed class SocketAcceptor
- {
- private readonly ObjectPool<SocketAsyncEventArgs> acceptAsyncEventArgsPool;
- private readonly ObjectPool<SocketAsyncEventArgs> connectAsyncEventArgsPool;
- private readonly ObjectPool<SocketAsyncEventArgs> disconnectAsyncEventArgsPool;
-
- private void HandleIOCompleted(object? sender, SocketAsyncEventArgs args)
- {
- switch (args.LastOperation)
- {
- case SocketAsyncOperation.Accept:
- AsyncAcceptToken asyncAcceptToken = (AsyncAcceptToken)args.UserToken;
-
- if (asyncAcceptToken.CancellationToken.IsCancellationRequested)
- {
- asyncAcceptToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncAcceptToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncAcceptToken.CompletionSource.SetResult(args.AcceptSocket);
- }
- }
-
- acceptAsyncEventArgsPool.Return(args);
-
- break;
-
- case SocketAsyncOperation.Connect:
- AsyncConnectToken asyncConnectToken = (AsyncConnectToken)args.UserToken;
-
- if (asyncConnectToken.CancellationToken.IsCancellationRequested)
- {
- asyncConnectToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncConnectToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncConnectToken.CompletionSource.SetResult(true);
- }
- }
-
- connectAsyncEventArgsPool.Return(args);
-
- break;
-
- case SocketAsyncOperation.Disconnect:
- AsyncDisconnectToken asyncDisconnectToken = (AsyncDisconnectToken)args.UserToken;
-
- if (asyncDisconnectToken.CancellationToken.IsCancellationRequested)
- {
- asyncDisconnectToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncDisconnectToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncDisconnectToken.CompletionSource.SetResult(true);
- }
- }
-
- disconnectAsyncEventArgsPool.Return(args);
-
- break;
-
- default:
- throw new InvalidOperationException(
- $"The {nameof(SocketAcceptor)} class doesn't support the {args.LastOperation} operation.");
- }
- }
-
- private readonly struct AsyncAcceptToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<Socket> CompletionSource;
-
- public AsyncAcceptToken(TaskCompletionSource<Socket> tcs, CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- private readonly struct AsyncConnectToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<bool> CompletionSource;
-
- public AsyncConnectToken(TaskCompletionSource<bool> tcs, CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- private readonly struct AsyncDisconnectToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<bool> CompletionSource;
-
- public AsyncDisconnectToken(TaskCompletionSource<bool> tcs, CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal SocketAcceptor(int maxPooledObjects = 10)
- {
- acceptAsyncEventArgsPool =
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- maxPooledObjects);
-
- connectAsyncEventArgsPool =
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- maxPooledObjects);
-
- disconnectAsyncEventArgsPool =
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- maxPooledObjects);
-
- for (int i = 0; i < maxPooledObjects; i++)
- {
- SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
- acceptArgs.Completed += HandleIOCompleted;
- acceptAsyncEventArgsPool.Return(acceptArgs);
-
- SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
- connectArgs.Completed += HandleIOCompleted;
- connectAsyncEventArgsPool.Return(connectArgs);
-
- SocketAsyncEventArgs disconnectArgs = new SocketAsyncEventArgs();
- disconnectArgs.Completed += HandleIOCompleted;
- connectAsyncEventArgsPool.Return(disconnectArgs);
- }
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket accept operation.
- /// </summary>
- /// <param name="socket">The socket which should be used to accept an incoming connection attempt.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- /// <returns>The accepted socket.</returns>
- public Task<Socket> AcceptAsync(Socket socket, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<Socket> tcs = new TaskCompletionSource<Socket>();
-
- SocketAsyncEventArgs args = acceptAsyncEventArgsPool.Get();
- args.UserToken = new AsyncAcceptToken(tcs, cancellationToken);
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- acceptAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the accept operation doesn't complete synchronously, return the awaitable task
- if (socket.AcceptAsync(args)) return tcs.Task;
-
- Socket result = args.AcceptSocket;
-
- acceptAsyncEventArgsPool.Return(args);
-
- return Task.FromResult(result);
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket connect operation.
- /// </summary>
- /// <param name="socket">The socket which should asynchronously connect to the remote endpoint.</param>
- /// <param name="remoteEndPoint">The remote endpoint to which the socket should connect.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- public Task ConnectAsync(Socket socket, EndPoint remoteEndPoint, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-
- SocketAsyncEventArgs args = connectAsyncEventArgsPool.Get();
- args.RemoteEndPoint = remoteEndPoint;
- args.UserToken = new AsyncConnectToken(tcs, cancellationToken);
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- connectAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the connect operation doesn't complete synchronously, return the awaitable task
- if (socket.ConnectAsync(args)) return tcs.Task;
-
- connectAsyncEventArgsPool.Return(args);
-
- return Task.CompletedTask;
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket disconnect operation.
- /// </summary>
- /// <param name="socket">The socket which should asynchronously disconnect from its remote endpoint.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- public Task DisconnectAsync(Socket socket, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-
- SocketAsyncEventArgs args = connectAsyncEventArgsPool.Get();
- args.UserToken = new AsyncDisconnectToken(tcs, cancellationToken);
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- disconnectAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the disconnect operation doesn't complete synchronously, return the awaitable task
- if (socket.DisconnectAsync(args)) return tcs.Task;
-
- connectAsyncEventArgsPool.Return(args);
-
- return Task.CompletedTask;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketClient.cs b/NetSharp/NetSharp/Deprecated/SocketClient.cs
@@ -1,132 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using NetSharp.Utils;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- public class SocketClient : IDisposable
- {
- private readonly ObjectPool<SocketAsyncEventArgs> transmissionArgsPool;
-
- /// <summary>
- /// Destroys a socket client instance.
- /// </summary>
- ~SocketClient()
- {
- Dispose(false);
- }
-
- protected readonly Socket transmitterSocket;
-
- /// <summary>
- /// Implementation of dispose pattern.
- /// </summary>
- /// <param name="disposing">
- /// Whether this method is being called by the object finalizer, or by the <see cref="Dispose()"/> method.
- /// </param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- transmitterSocket.Dispose();
- }
- }
-
- public SocketClient(AddressFamily transmitterAddressFamily, SocketType transmitterSocketType,
- ProtocolType transmitterProtocolType)
- {
- transmitterSocket = new Socket(transmitterAddressFamily, transmitterSocketType, transmitterProtocolType);
-
- transmissionArgsPool = new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>());
- }
-
- /// <inheritdoc />
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- public async ValueTask<TransmissionResult> ReceiveAsync(EndPoint remoteEndPoint, SocketFlags receiveFlags, Memory<byte> receiveBuffer,
- CancellationToken cancellationToken = default)
- {
- SocketAsyncEventArgs transmissionArgs = transmissionArgsPool.Get();
-
- TransmissionResult receiveResult =
- await SocketOperations.ReceiveFromAsync(transmissionArgs, transmitterSocket,
- remoteEndPoint, receiveFlags, receiveBuffer, cancellationToken).ConfigureAwait(false);
-
- transmissionArgsPool.Return(transmissionArgs);
-
- return receiveResult;
- }
-
- public async ValueTask<TransmissionResult> SendAsync(EndPoint remoteEndPoint, SocketFlags sendFlags, Memory<byte> sendBuffer,
- CancellationToken cancellationToken = default)
- {
- SocketAsyncEventArgs transmissionArgs = transmissionArgsPool.Get();
-
- TransmissionResult sendResult =
- await SocketOperations.SendToAsync(transmissionArgs, transmitterSocket,
- remoteEndPoint, sendFlags, sendBuffer, cancellationToken).ConfigureAwait(false);
-
- transmissionArgsPool.Return(transmissionArgs);
-
- return sendResult;
- }
-
- public Task<bool> TryBindAsync(EndPoint localEndPoint, TimeSpan timeout)
- {
- using CancellationTokenSource cts = new CancellationTokenSource(timeout);
-
- try
- {
- return Task.Run(() =>
- {
- transmitterSocket.Bind(localEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return Task.FromResult(false);
- }
- catch (SocketException ex)
- {
- Console.WriteLine($"Socket exception on binding socket to {localEndPoint}: {ex}");
- return Task.FromResult(false);
- }
- }
-
- public Task<bool> TryConnectAsync(EndPoint remoteEndPoint, TimeSpan timeout)
- {
- using CancellationTokenSource cts = new CancellationTokenSource(timeout);
-
- try
- {
- return Task.Run(() =>
- {
- transmitterSocket.Connect(remoteEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return Task.FromResult(false);
- }
- catch (SocketException ex)
- {
- Console.WriteLine($"Socket exception on connecting to {remoteEndPoint}: {ex}");
- return Task.FromResult(false);
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketOperationTokens.cs b/NetSharp/NetSharp/Deprecated/SocketOperationTokens.cs
@@ -1,80 +0,0 @@
-using NetSharp.Utils;
-
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- internal readonly struct AsyncAcceptToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<Socket> CompletionSource;
-
- public AsyncAcceptToken(in TaskCompletionSource<Socket> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal readonly struct AsyncConnectToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<Socket> CompletionSource;
-
- public AsyncConnectToken(in TaskCompletionSource<Socket> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal readonly struct AsyncDisconnectToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<bool> CompletionSource;
-
- public AsyncDisconnectToken(in TaskCompletionSource<bool> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal readonly struct AsyncReadToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
-
- public AsyncReadToken(in TaskCompletionSource<TransmissionResult> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal readonly struct AsyncWriteToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
-
- public AsyncWriteToken(in TaskCompletionSource<TransmissionResult> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal readonly struct AsyncReadFromToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
-
- public AsyncReadFromToken(in TaskCompletionSource<TransmissionResult> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketOperations.cs b/NetSharp/NetSharp/Deprecated/SocketOperations.cs
@@ -1,469 +0,0 @@
-using NetSharp.Utils;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides helper awaitable functions for wrapping the <see cref="SocketAsyncEventArgs"/> pattern.
- /// </summary>
- public static class SocketOperations
- {
- private static void HandleIOCompleted(object? sender, SocketAsyncEventArgs args)
- {
- args.Completed -= HandleIOCompleted;
-
- switch (args.LastOperation)
- {
- case SocketAsyncOperation.Receive:
- AsyncReadToken asyncReceiveToken = (AsyncReadToken)args.UserToken;
-
- if (asyncReceiveToken.CancellationToken.IsCancellationRequested)
- {
- asyncReceiveToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncReceiveToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else if (args.BytesTransferred > 0)
- {
- TransmissionResult result = new TransmissionResult(args);
-
- asyncReceiveToken.CompletionSource.SetResult(result);
- }
- else
- {
- asyncReceiveToken.CompletionSource.SetException(
- new Exception($"Receive method received 0 bytes from remote endpoint!"));
- }
- }
-
- break;
-
- case SocketAsyncOperation.ReceiveFrom:
- AsyncReadFromToken asyncReceiveFromToken = (AsyncReadFromToken)args.UserToken;
-
- if (asyncReceiveFromToken.CancellationToken.IsCancellationRequested)
- {
- asyncReceiveFromToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncReceiveFromToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- TransmissionResult result = new TransmissionResult(args);
-
- asyncReceiveFromToken.CompletionSource.SetResult(result);
- }
- }
-
- break;
-
- case SocketAsyncOperation.Send:
- AsyncWriteToken asyncSendToken = (AsyncWriteToken)args.UserToken;
-
- if (asyncSendToken.CancellationToken.IsCancellationRequested)
- {
- asyncSendToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncSendToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- TransmissionResult result = new TransmissionResult(args);
-
- asyncSendToken.CompletionSource.SetResult(result);
- }
- }
-
- break;
-
- case SocketAsyncOperation.SendTo:
- AsyncWriteToToken asyncSendToToken = (AsyncWriteToToken)args.UserToken;
-
- if (asyncSendToToken.CancellationToken.IsCancellationRequested)
- {
- asyncSendToToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncSendToToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- TransmissionResult result = new TransmissionResult(args);
-
- asyncSendToToken.CompletionSource.SetResult(result);
- }
- }
-
- break;
-
- case SocketAsyncOperation.Accept:
- AsyncAcceptToken asyncAcceptToken = (AsyncAcceptToken)args.UserToken;
-
- if (asyncAcceptToken.CancellationToken.IsCancellationRequested)
- {
- asyncAcceptToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncAcceptToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncAcceptToken.CompletionSource.SetResult(args.AcceptSocket);
- }
- }
-
- break;
-
- case SocketAsyncOperation.Connect:
- AsyncConnectToken asyncConnectToken = (AsyncConnectToken)args.UserToken;
-
- if (asyncConnectToken.CancellationToken.IsCancellationRequested)
- {
- asyncConnectToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncConnectToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncConnectToken.CompletionSource.SetResult(args.ConnectSocket);
- }
- }
-
- break;
-
- case SocketAsyncOperation.Disconnect:
- AsyncDisconnectToken asyncDisconnectToken = (AsyncDisconnectToken)args.UserToken;
-
- if (asyncDisconnectToken.CancellationToken.IsCancellationRequested)
- {
- asyncDisconnectToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncDisconnectToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncDisconnectToken.CompletionSource.SetResult(true);
- }
- }
-
- break;
-
- default:
- throw new InvalidOperationException(
- $"{nameof(SocketOperations)} doesn't support the {args.LastOperation} operation.");
- }
- }
-
- private readonly struct AsyncWriteToToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
-
- public AsyncWriteToToken(in TaskCompletionSource<TransmissionResult> tcs, in CancellationToken cancellationToken = default)
- {
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- public static ValueTask<Socket> AcceptAsync(SocketAsyncEventArgs clientAcceptArgs, Socket socket,
- CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<Socket> tcs = new TaskCompletionSource<Socket>();
-
- clientAcceptArgs.UserToken = new AsyncAcceptToken(tcs, cancellationToken);
-
- clientAcceptArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- acceptAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the accept operation doesn't complete synchronously, return the awaitable task
- if (socket.AcceptAsync(clientAcceptArgs)) return new ValueTask<Socket>(tcs.Task);
-
- Socket result = clientAcceptArgs.AcceptSocket;
- clientAcceptArgs.Completed -= HandleIOCompleted;
-
- return new ValueTask<Socket>(result);
- }
-
- public static ValueTask<Socket> ConnectAsync(SocketAsyncEventArgs clientConnectArgs, Socket socket, EndPoint remoteEndPoint,
- CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<Socket> tcs = new TaskCompletionSource<Socket>();
-
- clientConnectArgs.RemoteEndPoint = remoteEndPoint;
- clientConnectArgs.UserToken = new AsyncConnectToken(tcs, cancellationToken);
-
- clientConnectArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- connectAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the connect operation doesn't complete synchronously, return the awaitable task
- if (socket.ConnectAsync(clientConnectArgs)) return new ValueTask<Socket>(tcs.Task);
-
- Socket result = clientConnectArgs.ConnectSocket;
- clientConnectArgs.Completed -= HandleIOCompleted;
-
- return new ValueTask<Socket>(result);
- }
-
- public static ValueTask DisconnectAsync(SocketAsyncEventArgs clientDisconnectArgs, Socket socket,
- CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-
- clientDisconnectArgs.UserToken = new AsyncDisconnectToken(tcs, cancellationToken);
-
- clientDisconnectArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- disconnectAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the disconnect operation doesn't complete synchronously, return the awaitable task
- if (socket.DisconnectAsync(clientDisconnectArgs)) return new ValueTask(tcs.Task);
-
- clientDisconnectArgs.Completed -= HandleIOCompleted;
-
- return new ValueTask();
- }
-
- public static ValueTask<TransmissionResult> ReceiveAsync(SocketAsyncEventArgs socketArgs, Socket socket, EndPoint remoteEndPoint,
- SocketFlags socketFlags, Memory<byte> inputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
-
- socketArgs.SetBuffer(inputBuffer);
- socketArgs.SocketFlags = socketFlags;
- socketArgs.RemoteEndPoint = remoteEndPoint;
- socketArgs.UserToken = new AsyncReadToken(tcs, cancellationToken);
-
- socketArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- receiveBufferPool.Return(rentedReceiveFromBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- receiveAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the receive operation doesn't complete synchronously, returns the awaitable task
- if (socket.ReceiveAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
-
- socketArgs.Completed -= HandleIOCompleted;
-
- TransmissionResult result = new TransmissionResult(socketArgs);
-
- return new ValueTask<TransmissionResult>(result);
- }
-
- public static ValueTask<TransmissionResult> ReceiveFromAsync(SocketAsyncEventArgs socketArgs, Socket socket, EndPoint remoteEndPoint,
- SocketFlags socketFlags, Memory<byte> inputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
-
- socketArgs.SetBuffer(inputBuffer);
- socketArgs.SocketFlags = socketFlags;
- socketArgs.RemoteEndPoint = remoteEndPoint;
- socketArgs.UserToken = new AsyncReadFromToken(tcs, cancellationToken);
-
- socketArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- receiveBufferPool.Return(rentedReceiveFromBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- receiveAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the receive operation doesn't complete synchronously, returns the awaitable task
- if (socket.ReceiveFromAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
-
- socketArgs.Completed -= HandleIOCompleted;
-
- TransmissionResult result = new TransmissionResult(socketArgs);
-
- return new ValueTask<TransmissionResult>(result);
- }
-
- public static ValueTask<TransmissionResult> SendAsync(SocketAsyncEventArgs socketArgs, Socket socket, EndPoint remoteEndPoint,
- SocketFlags socketFlags, Memory<byte> outputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
-
- socketArgs.SetBuffer(outputBuffer);
- socketArgs.SocketFlags = socketFlags;
- socketArgs.RemoteEndPoint = remoteEndPoint;
- socketArgs.UserToken = new AsyncWriteToken(tcs, cancellationToken);
-
- socketArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- sendBufferPool.Return(rentedSendToBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- sendAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the send operation doesn't complete synchronously, return the awaitable task
- if (socket.SendAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
-
- socketArgs.Completed -= HandleIOCompleted;
-
- TransmissionResult result = new TransmissionResult(socketArgs);
-
- return new ValueTask<TransmissionResult>(result);
- }
-
- public static ValueTask<TransmissionResult> SendToAsync(SocketAsyncEventArgs socketArgs, Socket socket, EndPoint remoteEndPoint,
- SocketFlags socketFlags, Memory<byte> outputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
-
- socketArgs.SetBuffer(outputBuffer);
- socketArgs.SocketFlags = socketFlags;
- socketArgs.RemoteEndPoint = remoteEndPoint;
- socketArgs.UserToken = new AsyncWriteToToken(tcs, cancellationToken);
-
- socketArgs.Completed += HandleIOCompleted;
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- sendBufferPool.Return(rentedSendToBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- sendAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the send operation doesn't complete synchronously, return the awaitable task
- if (socket.SendToAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
-
- socketArgs.Completed -= HandleIOCompleted;
-
- TransmissionResult result = new TransmissionResult(socketArgs);
-
- return new ValueTask<TransmissionResult>(result);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketOptions.cs b/NetSharp/NetSharp/Deprecated/SocketOptions.cs
@@ -1,106 +0,0 @@
-using System.Net;
-using System.Net.Sockets;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows for manipulation of socket options.
- /// </summary>
- public abstract class SocketOptions
- {
- /// <summary>
- /// The <see cref="Socket"/> instance whose settings are being managed.
- /// </summary>
- protected readonly Socket managedSocket;
-
- /// <summary>
- /// Initialises a new instance of the <see cref="SocketOptions"/> class.
- /// </summary>
- /// <param name="socket">The <see cref="Socket"/> instance whose options should be managed.</param>
- protected SocketOptions(ref Socket socket)
- {
- managedSocket = socket;
- }
-
- /// <summary>
- /// Whether this <see cref="Socket"/> can operate in dual IPv4 / IPv6 mode.
- /// </summary>
- public bool DualMode { get { return managedSocket.DualMode; } set { managedSocket.DualMode = value; } }
-
- /// <summary>
- /// Whether sending a packet flushes underlying <see cref="NetworkStream"/>.
- /// </summary>
- /// <remarks>
- /// This value is only used in a <see cref="System.Net.Sockets.TcpClient"/> instance, which uses a <see cref="NetworkStream"/>
- /// to send and receive data. A <see cref="System.Net.Sockets.UdpClient"/> is unaffected by this value.
- /// </remarks>
- public bool ForceFlush { get; set; } = true;
-
- /// <summary>
- /// Whether this <see cref="Socket"/> is allowed to fragment frames that are too large to send in one go.
- /// </summary>
- public bool Fragment { get { return !managedSocket.DontFragment; } set { managedSocket.DontFragment = !value; } }
-
- /// <summary>
- /// The hop limit for packets sent by this <see cref="Socket"/>. Comparable to IPv4s TTL (Time To Live).
- /// </summary>
- public abstract int HopLimit { get; set; }
-
- /// <summary>
- /// Whether a checksum should be created for each UDP packet sent.
- /// </summary>
- public bool IsChecksumEnabled
- {
- get { return (int)managedSocket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoChecksum) == 0; }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoChecksum, value ? 0 : -1); }
- }
-
- /// <summary>
- /// Whether the packet should be sent directly to its destination or allowed to be routed through multiple destinations
- /// first.
- /// </summary>
- public abstract bool IsRoutingEnabled { get; set; }
-
- /// <summary>
- /// The local <see cref="EndPoint"/> for the <see cref="managedSocket"/>.
- /// </summary>
- public EndPoint LocalEndPoint { get { return managedSocket.LocalEndPoint; } }
-
- /// <summary>
- /// The local <see cref="IPEndPoint"/> for this <see cref="Socket"/> instance.
- /// </summary>
- public EndPoint LocalIPEndPoint
- {
- get
- {
- return managedSocket?.LocalEndPoint as IPEndPoint ?? new IPEndPoint(IPAddress.None, IPEndPoint.MinPort);
- }
- }
-
- /// <summary>
- /// The remote <see cref="EndPoint"/> for the <see cref="managedSocket"/>.
- /// </summary>
- public EndPoint RemoteEndPoint { get { return managedSocket.RemoteEndPoint; } }
-
- /// <summary>
- /// The remote <see cref="IPEndPoint"/> that this <see cref="Socket"/> instance communicates with.
- /// </summary>
- public EndPoint RemoteIPEndPoint
- {
- get
- {
- return managedSocket?.RemoteEndPoint as IPEndPoint ?? new IPEndPoint(IPAddress.None, IPEndPoint.MinPort);
- }
- }
-
- /// <summary>
- /// The 'Time To Live' for this <see cref="Socket"/>.
- /// </summary>
- public short Ttl { get { return managedSocket.Ttl; } set { managedSocket.Ttl = value; } }
-
- /// <summary>
- /// Whether this <see cref="Socket"/> should use a loopback address and bypass hardware.
- /// </summary>
- public abstract bool UseLoopback { get; set; }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketReader.cs b/NetSharp/NetSharp/Deprecated/SocketReader.cs
@@ -1,153 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using NetSharp.Utils;
-
-using System;
-using System.Buffers;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Helper class providing awaitable wrappers around asynchronous Receive and ReceiveFrom operations.
- /// </summary>
- public sealed class SocketReader
- {
- private readonly int PacketBufferLength;
- private readonly ObjectPool<SocketAsyncEventArgs> receiveFromAsyncEventArgsPool;
- private readonly ArrayPool<byte> receiveFromBufferPool;
-
- private void HandleIOCompleted(object? sender, SocketAsyncEventArgs args)
- {
- switch (args.LastOperation)
- {
- case SocketAsyncOperation.ReceiveFrom:
- AsyncReadToken asyncReceiveFromToken = (AsyncReadToken)args.UserToken;
-
- if (asyncReceiveFromToken.CancellationToken.IsCancellationRequested)
- {
- asyncReceiveFromToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncReceiveFromToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- args.MemoryBuffer.CopyTo(asyncReceiveFromToken.UserBuffer);
-
- TransmissionResult result = new TransmissionResult(args);
-
- asyncReceiveFromToken.CompletionSource.SetResult(result);
- }
- }
-
- receiveFromBufferPool.Return(asyncReceiveFromToken.RentedBuffer, true);
- receiveFromAsyncEventArgsPool.Return(args);
-
- break;
-
- default:
- throw new InvalidOperationException(
- $"The {nameof(SocketReader)} class doesn't support the {args.LastOperation} operation.");
- }
- }
-
- private readonly struct AsyncReadToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
- public readonly byte[] RentedBuffer;
- public readonly Memory<byte> UserBuffer;
-
- public AsyncReadToken(byte[] rentedBuffer, Memory<byte> userBuffer, TaskCompletionSource<TransmissionResult> tcs,
- CancellationToken cancellationToken = default)
- {
- RentedBuffer = rentedBuffer;
- UserBuffer = userBuffer;
-
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal SocketReader(int packetBufferLength = NetworkPacket.PacketSize, int maxPooledObjects = 10,
- bool preallocateBuffers = false)
- {
- PacketBufferLength = packetBufferLength;
-
- receiveFromBufferPool = ArrayPool<byte>.Create(packetBufferLength, maxPooledObjects);
-
- receiveFromAsyncEventArgsPool =
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- maxPooledObjects);
-
- for (int i = 0; i < maxPooledObjects; i++)
- {
- SocketAsyncEventArgs receiveFromArgs = new SocketAsyncEventArgs();
- receiveFromArgs.Completed += HandleIOCompleted;
- receiveFromAsyncEventArgsPool.Return(receiveFromArgs);
- }
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket receive operation.
- /// </summary>
- /// <param name="socket">The socket which should receive data from the remote endpoint.</param>
- /// <param name="remoteEndPoint">The remove endpoint from which data should be received.</param>
- /// <param name="socketFlags">The socket flags associated with the receive operation.</param>
- /// <param name="inputBuffer">The memory buffer into which received data will be stored.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- /// <returns>The result of the receive operation.</returns>
- public Task<TransmissionResult> ReceiveFromAsync(Socket socket, EndPoint remoteEndPoint, SocketFlags socketFlags,
- Memory<byte> inputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
-
- byte[] rentedReceiveFromBuffer = receiveFromBufferPool.Rent(PacketBufferLength);
- Memory<byte> rentedReceiveFromBufferMemory = new Memory<byte>(rentedReceiveFromBuffer);
-
- SocketAsyncEventArgs args = receiveFromAsyncEventArgsPool.Get();
- args.SetBuffer(rentedReceiveFromBufferMemory);
- args.SocketFlags = socketFlags;
- args.RemoteEndPoint = remoteEndPoint;
- args.UserToken = new AsyncReadToken(rentedReceiveFromBuffer, inputBuffer, tcs, cancellationToken);
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- receiveBufferPool.Return(rentedReceiveFromBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- receiveAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the receive operation doesn't complete synchronously, returns the awaitable task
- if (socket.ReceiveFromAsync(args)) return tcs.Task;
-
- args.MemoryBuffer.CopyTo(inputBuffer);
-
- TransmissionResult result = new TransmissionResult(args);
-
- receiveFromBufferPool.Return(rentedReceiveFromBuffer, true);
- receiveFromAsyncEventArgsPool.Return(args);
-
- return Task.FromResult(result);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketServer.cs b/NetSharp/NetSharp/Deprecated/SocketServer.cs
@@ -1,121 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using NetSharp.Utils;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- public class SocketServer : IDisposable
- {
- private readonly ObjectPool<SocketAsyncEventArgs> transmissionArgsPool;
-
- /// <summary>
- /// Destroys a socket server instance.
- /// </summary>
- ~SocketServer()
- {
- Dispose(false);
- }
-
- /// <summary>
- /// The socket which should be used to listen for incoming data and to send outgoing data.
- /// </summary>
- protected readonly Socket listenerSocket;
-
- /// <summary>
- /// Implementation of dispose pattern.
- /// </summary>
- /// <param name="disposing">
- /// Whether this method is being called by the object finalizer, or by the <see cref="Dispose()"/> method.
- /// </param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- listenerSocket.Dispose();
- }
- }
-
- public SocketServer(AddressFamily listenerAddressFamily, SocketType listenerSocketType,
- ProtocolType listenerProtocolType)
- {
- listenerSocket = new Socket(listenerAddressFamily, listenerSocketType, listenerProtocolType);
-
- transmissionArgsPool = new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>());
- }
-
- /// <inheritdoc />
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- public async ValueTask<TransmissionResult> ReceiveAsync(EndPoint remoteEndPoint, SocketFlags receiveFlags, Memory<byte> receiveBuffer,
- CancellationToken cancellationToken = default)
- {
- SocketAsyncEventArgs transmissionArgs = transmissionArgsPool.Get();
-
- TransmissionResult receiveResult =
- await SocketOperations.ReceiveFromAsync(transmissionArgs, listenerSocket, remoteEndPoint, receiveFlags,
- receiveBuffer, cancellationToken).ConfigureAwait(false);
-
- transmissionArgsPool.Return(transmissionArgs);
-
- return receiveResult;
- }
-
- public async ValueTask<TransmissionResult> SendAsync(EndPoint remoteEndPoint, SocketFlags sendFlags, Memory<byte> sendBuffer,
- CancellationToken cancellationToken = default)
- {
- SocketAsyncEventArgs transmissionArgs = transmissionArgsPool.Get();
-
- TransmissionResult sendResult =
- await SocketOperations.SendToAsync(transmissionArgs, listenerSocket, remoteEndPoint, sendFlags,
- sendBuffer, cancellationToken).ConfigureAwait(false);
-
- transmissionArgsPool.Return(transmissionArgs);
-
- return sendResult;
- }
-
- public async Task<RemoteSocketClient> AcceptAsync(CancellationToken cancellationToken = default)
- {
- using SocketAsyncEventArgs clientAcceptArgs = new SocketAsyncEventArgs();
-
- Socket clientSocket = await SocketOperations
- .AcceptAsync(clientAcceptArgs, listenerSocket, cancellationToken).ConfigureAwait(false);
-
- return new RemoteSocketClient(clientSocket);
- }
-
- public Task<bool> TryBindAsync(EndPoint localEndPoint, TimeSpan timeout)
- {
- using CancellationTokenSource cts = new CancellationTokenSource(timeout);
-
- try
- {
- return Task.Run(() =>
- {
- listenerSocket.Bind(localEndPoint);
-
- return true;
- }, cts.Token);
- }
- catch (TaskCanceledException)
- {
- return Task.FromResult(false);
- }
- catch (SocketException ex)
- {
- Console.WriteLine($"Socket exception on binding socket to {localEndPoint}: {ex}");
- return Task.FromResult(false);
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/SocketWriter.cs b/NetSharp/NetSharp/Deprecated/SocketWriter.cs
@@ -1,144 +0,0 @@
-using Microsoft.Extensions.ObjectPool;
-
-using System;
-using System.Buffers;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Helper class providing awaitable wrappers around asynchronous Send and SendTo operations.
- /// </summary>
- public sealed class SocketWriter
- {
- private readonly int PacketBufferLength;
- private readonly ObjectPool<SocketAsyncEventArgs> sendToAsyncEventArgsPool;
- private readonly ArrayPool<byte> sendToBufferPool;
-
- private void HandleIOCompleted(object? sender, SocketAsyncEventArgs args)
- {
- switch (args.LastOperation)
- {
- case SocketAsyncOperation.SendTo:
- AsyncWriteToken asyncSendToToken = (AsyncWriteToken)args.UserToken;
-
- if (asyncSendToToken.CancellationToken.IsCancellationRequested)
- {
- asyncSendToToken.CompletionSource.SetCanceled();
- }
- else
- {
- if (args.SocketError != SocketError.Success)
- {
- asyncSendToToken.CompletionSource.SetException(
- new SocketException((int)args.SocketError));
- }
- else
- {
- asyncSendToToken.CompletionSource.SetResult(args.BytesTransferred);
- }
- }
-
- sendToBufferPool.Return(asyncSendToToken.RentedBuffer, true);
- sendToAsyncEventArgsPool.Return(args);
- break;
-
- default:
- throw new InvalidOperationException(
- $"The {nameof(SocketWriter)} class doesn't support the {args.LastOperation} operation.");
- }
- }
-
- private readonly struct AsyncWriteToken
- {
- public readonly CancellationToken CancellationToken;
- public readonly TaskCompletionSource<int> CompletionSource;
- public readonly byte[] RentedBuffer;
-
- public AsyncWriteToken(byte[] rentedBuffer, TaskCompletionSource<int> tcs,
- CancellationToken cancellationToken = default)
- {
- RentedBuffer = rentedBuffer;
-
- CompletionSource = tcs;
- CancellationToken = cancellationToken;
- }
- }
-
- internal SocketWriter(int packetBufferLength = NetworkPacket.PacketSize, int maxPooledObjects = 10,
- bool preallocateBuffers = false)
- {
- PacketBufferLength = packetBufferLength;
-
- sendToBufferPool = ArrayPool<byte>.Create(packetBufferLength, maxPooledObjects);
-
- sendToAsyncEventArgsPool =
- new DefaultObjectPool<SocketAsyncEventArgs>(new DefaultPooledObjectPolicy<SocketAsyncEventArgs>(),
- maxPooledObjects);
-
- for (int i = 0; i < maxPooledObjects; i++)
- {
- SocketAsyncEventArgs sendToArgs = new SocketAsyncEventArgs();
- sendToArgs.Completed += HandleIOCompleted;
- sendToAsyncEventArgsPool.Return(sendToArgs);
- }
- }
-
- /// <summary>
- /// Provides an awaitable wrapper around an asynchronous socket send operation.
- /// </summary>
- /// <param name="socket">The socket which should send the data to the remote endpoint.</param>
- /// <param name="remoteEndPoint">The remote endpoint to which data should be written.</param>
- /// <param name="socketFlags">The socket flags associated with the send operation.</param>
- /// <param name="outputBuffer">The data buffer which should be sent.</param>
- /// <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- /// <returns>The number of bytes of data which were written to the remote endpoint.</returns>
- public ValueTask<int> SendToAsync(Socket socket, EndPoint remoteEndPoint, SocketFlags socketFlags,
- Memory<byte> outputBuffer, CancellationToken cancellationToken = default)
- {
- TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
-
- byte[] rentedSendToBuffer = sendToBufferPool.Rent(PacketBufferLength);
- Memory<byte> rentedSendToBufferMemory = new Memory<byte>(rentedSendToBuffer);
-
- outputBuffer.CopyTo(rentedSendToBufferMemory);
-
- SocketAsyncEventArgs args = sendToAsyncEventArgsPool.Get();
- args.SetBuffer(rentedSendToBufferMemory);
- args.SocketFlags = socketFlags;
- args.RemoteEndPoint = remoteEndPoint;
- args.UserToken = new AsyncWriteToken(rentedSendToBuffer, tcs, cancellationToken);
-
- /*
- // register cleanup action for when the cancellation token is thrown
- cancellationToken.Register(() =>
- {
- tcs.SetCanceled();
-
- sendBufferPool.Return(rentedSendToBuffer, true);
-
- //TODO this is probably a hideous solution. find a better one
- args.Completed -= HandleIOCompleted;
- args.Dispose();
-
- SocketAsyncEventArgs newArgs = new SocketAsyncEventArgs();
- newArgs.Completed += HandleIOCompleted;
- sendAsyncEventArgsPool.Return(newArgs);
- });
- */
-
- // if the send operation doesn't complete synchronously, return the awaitable task
- if (socket.SendToAsync(args)) return new ValueTask<int>(tcs.Task);
-
- int result = args.BytesTransferred;
-
- sendToBufferPool.Return(rentedSendToBuffer, true);
- sendToAsyncEventArgsPool.Return(args);
-
- return new ValueTask<int>(result);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/TcpClient.cs b/NetSharp/NetSharp/Deprecated/TcpClient.cs
@@ -1,64 +0,0 @@
-using NetSharp.Deprecated.Builtin;
-
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides methods for TCP communication with a connected <see cref="TcpServer"/> instance.
- /// </summary>
- public sealed class TcpClient : Client
- {
- /// <inheritdoc />
- public TcpClient() : base(SocketType.Stream, ProtocolType.Tcp)
- {
- }
-
- /// <inheritdoc />
- public override async Task<bool> SendBytesAsync(byte[] buffer, TimeSpan timeout)
- {
- SimpleDataPacket packet = new SimpleDataPacket(buffer);
- return await SendSimpleAsync(packet, timeout);
- }
-
- /// <inheritdoc />
- public override async Task<byte[]> SendBytesWithResponseAsync(byte[] buffer, TimeSpan timeout)
- {
- DataPacket packet = new DataPacket(buffer);
- DataResponsePacket response = await SendComplexAsync<DataPacket, DataResponsePacket>(packet, timeout);
-
- return response.ResponseBuffer.ToArray();
- }
-
- /// <inheritdoc />
- public override async Task<Rep> SendComplexAsync<Req, Rep>(Req request, TimeSpan timeout)
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
-
- request.BeforeSerialisation();
- Memory<byte> serialisedRequest = request.Serialise();
- SerialisedPacket rawRequest = new SerialisedPacket(serialisedRequest, packetTypeId);
- //await DoSendPacketAsync(socket, rawRequest, SocketFlags.None, timeout);
-
- //SerialisedPacket rawResponsePacket = await DoReceivePacketAsync(socket, SocketFlags.None, timeout);
- Rep responsePacket = new Rep();
- //responsePacket.Deserialise(rawResponsePacket.Contents);
- responsePacket.AfterDeserialisation();
-
- return responsePacket;
- }
-
- /// <inheritdoc />
- public override async Task<bool> SendSimpleAsync<Req>(Req request, TimeSpan timeout)
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
-
- request.BeforeSerialisation();
- Memory<byte> serialisedRequest = request.Serialise();
- SerialisedPacket rawRequest = new SerialisedPacket(serialisedRequest, packetTypeId);
- return false; //await DoSendPacketAsync(socket, rawRequest, SocketFlags.None, timeout);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/TcpServer.cs b/NetSharp/NetSharp/Deprecated/TcpServer.cs
@@ -1,129 +0,0 @@
-using NetSharp.Deprecated.Builtin;
-
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides methods for TCP communication with connected <see cref="TcpClient"/> instances.
- /// </summary>
- public sealed class TcpServer : Server
- {
- /// <inheritdoc />
- protected override async Task HandleClientAsync(ClientHandlerArgs args, CancellationToken cancellationToken)
- {
- Socket clientHandlerSocket = args.ClientSocket ?? new Socket(SocketType.Unknown, ProtocolType.Unknown);
- EndPoint remoteEp = clientHandlerSocket.RemoteEndPoint;
-
- logger.LogMessage($"Initialised client handler for client socket: [Remote EP: {remoteEp}]");
-
- try
- {
- do
- {
- // receive a single raw packet from the network
- SerialisedPacket rawRequest = SerialisedPacket.Null; //await DoReceivePacketAsync(clientHandlerSocket, SocketFlags.None, Timeout.InfiniteTimeSpan, cancellationToken);
-
- if (rawRequest.Equals(SerialisedPacket.Null) ||
- rawRequest.Type == PacketRegistry.GetPacketId<DisconnectPacket>())
- {
- logger.LogMessage(
- $"Received a disconnect packet from client socket: [Remote EP: {remoteEp}]");
- break;
- }
-
- IRequestPacket? requestPacket = DeserialiseRequestPacket(rawRequest.Type, in rawRequest);
- Type requestPacketType = PacketRegistry.GetPacketType(rawRequest.Type);
-
- // the request packet is only null if no packet handler was registered for it
- if (requestPacket == default) continue;
-
- logger.LogMessage($"Received {rawRequest.Contents.Length} bytes from {remoteEp}");
-
- logger.LogMessage($"Received request: {Encoding.UTF8.GetString(rawRequest.Contents.Span)}");
-
- IResponsePacket<IRequestPacket>? responsePacket =
- HandleRequestPacket(rawRequest.Type, requestPacket, remoteEp);
-
- // the response packet is only null if the given request packet was registered as a 'simple' request packet
- if (responsePacket == default) continue;
-
- Type? responsePacketType =
- PacketRegistry.GetResponsePacketType(requestPacketType);
-
- if (responsePacketType == default)
- {
- logger.LogError(
- $"Response packet type for request packet of type {requestPacketType} is null");
- continue;
- }
-
- SerialisedPacket rawResponse = SerialisedPacket.From(responsePacket);
- // uint responsePacketTypeId = PacketRegistry.GetPacketId(responsePacketType);
- // responsePacket.BeforeSerialisation();
- // SerialisedPacket rawResponse = new SerialisedPacket(responsePacket.Serialise(), responsePacketTypeId);
-
- // echo back the processed raw response to the network
- bool sentCorrectly = false; //await DoSendPacketAsync(clientHandlerSocket, rawResponse, SocketFlags.None, NetworkOperationTimeout, cancellationToken);
-
- if (!sentCorrectly)
- {
- logger.LogMessage(
- $"Could not send response back to client socket: [Remote EP: {remoteEp}]");
- }
-
- logger.LogMessage($"Sent {rawResponse.Contents.Length} bytes to {remoteEp}");
- } while (true);
- }
- finally
- {
- logger.LogMessage($"Stopping client handler for client socket: [Remote EP: {remoteEp}]");
- }
- }
-
- /// <inheritdoc />
- public TcpServer(TimeSpan networkOperationTimeout) : base(SocketType.Stream, ProtocolType.Tcp, networkOperationTimeout)
- {
- }
-
- /// <inheritdoc />
- public TcpServer() : this(DefaultNetworkOperationTimeout)
- {
- }
-
- /// <inheritdoc />
- public override async Task RunAsync(EndPoint localEndPoint)
- {
- bool bound = await TryBindAsync(localEndPoint, Timeout.InfiniteTimeSpan);
-
- logger.LogMessage($"Is server socket bound: {bound}");
-
- if (!bound)
- {
- logger.LogError("Server socket was not bound successfully, shutting down server.");
- return;
- }
-
- socket.Listen(PendingConnectionBacklog);
-
- OnServerStarted();
- runServer = true;
-
- while (runServer)
- {
- Socket clientSocket = await socket.AcceptAsync();
- ClientHandlerArgs args = ClientHandlerArgs.ForTcpClientHandler(in clientSocket);
-
- await Task.Factory.StartNew(DoHandleClientAsync, args, serverShutdownCancellationToken,
- TaskCreationOptions.LongRunning, TaskScheduler.Default);
- }
-
- OnServerStopped();
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/TcpSocketOptions.cs b/NetSharp/NetSharp/Deprecated/TcpSocketOptions.cs
@@ -1,36 +0,0 @@
-using System.Net.Sockets;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows for manipulation of TCP socket options.
- /// </summary>
- public sealed class TcpSocketOptions : SocketOptions
- {
- /// <inheritdoc />
- public TcpSocketOptions(ref Socket socket) : base(ref socket)
- {
- }
-
- /// <inheritdoc />
- public override int HopLimit
- {
- get { return (int)managedSocket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.HopLimit); }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.HopLimit, value); }
- }
-
- /// <inheritdoc />
- public override bool IsRoutingEnabled
- {
- get { return !(bool)managedSocket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.DontRoute); }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.DontRoute, !value); }
- }
-
- /// <inheritdoc />
- public override bool UseLoopback
- {
- get { return (bool)managedSocket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.UseLoopback); }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.UseLoopback, value); }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/UdpClient.cs b/NetSharp/NetSharp/Deprecated/UdpClient.cs
@@ -1,68 +0,0 @@
-using NetSharp.Deprecated.Builtin;
-
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides methods for UDP communication with a connected <see cref="UdpServer"/> instance.
- /// </summary>
- public sealed class UdpClient : Client
- {
- /// <inheritdoc />
- public UdpClient() : base(SocketType.Dgram, ProtocolType.Udp)
- {
- }
-
- /// <inheritdoc />
- public override async Task<bool> SendBytesAsync(byte[] buffer, TimeSpan timeout)
- {
- SimpleDataPacket packet = new SimpleDataPacket(buffer);
- return await SendSimpleAsync(packet, timeout);
- }
-
- /// <inheritdoc />
- public override async Task<byte[]> SendBytesWithResponseAsync(byte[] buffer, TimeSpan timeout)
- {
- DataPacket packet = new DataPacket(buffer);
- DataResponsePacket response = await SendComplexAsync<DataPacket, DataResponsePacket>(packet, timeout);
-
- return response.ResponseBuffer.ToArray();
- }
-
- /// <inheritdoc />
- public override async Task<Rep> SendComplexAsync<Req, Rep>(Req request, TimeSpan timeout)
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
-
- request.BeforeSerialisation();
- Memory<byte> serialisedRequest = request.Serialise();
- SerialisedPacket rawRequest = new SerialisedPacket(serialisedRequest, packetTypeId);
-
- bool sentPacket = false; //await DoSendPacketToAsync(socket, remoteEndPoint, rawRequest, SocketFlags.None, timeout);
-
- //(SerialisedPacket rawResponsePacket, EndPoint responseEndPoint) = await DoReceivePacketFromAsync(socket, remoteEndPoint, SocketFlags.None, timeout);
- //remoteEndPoint = responseEndPoint;
-
- Rep responsePacket = new Rep();
- //responsePacket.Deserialise(rawResponsePacket.Contents);
- responsePacket.AfterDeserialisation();
-
- return responsePacket;
- }
-
- /// <inheritdoc />
- public override async Task<bool> SendSimpleAsync<Req>(Req request, TimeSpan timeout)
- {
- uint packetTypeId = PacketRegistry.GetPacketId<Req>();
-
- request.BeforeSerialisation();
- Memory<byte> serialisedRequest = request.Serialise();
- SerialisedPacket rawRequest = new SerialisedPacket(serialisedRequest, packetTypeId);
-
- return false; //await DoSendPacketToAsync(socket, remoteEndPoint, rawRequest, SocketFlags.None, timeout);
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/UdpServer.cs b/NetSharp/NetSharp/Deprecated/UdpServer.cs
@@ -1,169 +0,0 @@
-using NetSharp.Deprecated.Builtin;
-
-using System;
-using System.Collections.Concurrent;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Channels;
-using System.Threading.Tasks;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Provides methods for UDP communication with connected <see cref="UdpClient"/> instances.
- /// </summary>
- public sealed class UdpServer : Server
- {
- /// <summary>
- /// The options that should be applied to every channel created to handle a client.
- /// </summary>
- private static readonly UnboundedChannelOptions clientChannelOptions = new UnboundedChannelOptions
- {
- SingleReader = true,
- SingleWriter = true
- };
-
- /// <summary>
- /// Holds currently connected and active clients, as well as their current received packet queues.
- /// </summary>
- private readonly ConcurrentDictionary<EndPoint, Channel<SerialisedPacket>> activeClients;
-
- /// <inheritdoc />
- protected override async Task HandleClientAsync(ClientHandlerArgs args, CancellationToken cancellationToken)
- {
- EndPoint clientEndPoint = args.ClientEndPoint;
- Channel<SerialisedPacket> clientPacketBuffer = activeClients[clientEndPoint];
-
- logger.LogMessage($"Initialised client handler for client socket: [Remote EP: {clientEndPoint}]");
-
- try
- {
- do
- {
- // receive a single raw packet from the network
- SerialisedPacket rawRequest = await clientPacketBuffer.Reader.ReadAsync(cancellationToken);
-
- if (rawRequest.Equals(SerialisedPacket.Null) ||
- rawRequest.Type == PacketRegistry.GetPacketId<DisconnectPacket>())
- {
- logger.LogMessage(
- $"Received a disconnect packet from client socket: [Remote EP: {clientEndPoint}]");
- break;
- }
-
- IRequestPacket? requestPacket = DeserialiseRequestPacket(rawRequest.Type, in rawRequest);
- Type requestPacketType = PacketRegistry.GetPacketType(rawRequest.Type);
-
- // the request packet is only null if no packet handler was registered for it
- if (requestPacket == default) continue;
-
- logger.LogMessage($"Received {rawRequest.Contents.Length} bytes from {clientEndPoint}");
-
- logger.LogMessage($"Received request: {Encoding.UTF8.GetString(rawRequest.Contents.Span)}");
-
- IResponsePacket<IRequestPacket>? responsePacket =
- HandleRequestPacket(rawRequest.Type, requestPacket, clientEndPoint);
-
- // the response packet is only null if the given request packet was registered as a 'simple' request packet
- if (responsePacket == default) continue;
-
- Type? responsePacketType =
- PacketRegistry.GetResponsePacketType(requestPacketType);
-
- if (responsePacketType == default)
- {
- logger.LogError(
- $"Response packet type for request packet of type {requestPacketType} is null");
- continue;
- }
-
- SerialisedPacket rawResponse = SerialisedPacket.From(responsePacket);
- // uint responsePacketTypeId = PacketRegistry.GetPacketId(responsePacketType);
- // responsePacket.BeforeSerialisation();
- // SerialisedPacket rawResponse = new SerialisedPacket(responsePacket.Serialise(), responsePacketTypeId);
-
- // echo back the processed raw response to the network
- bool sentCorrectly = false; //await DoSendPacketToAsync(socket, clientEndPoint, rawResponse, SocketFlags.None,NetworkOperationTimeout, cancellationToken);
-
- if (!sentCorrectly)
- {
- logger.LogWarning(
- $"Could not send response back to client socket: [Remote EP: {clientEndPoint}]");
- }
- } while (true);
- }
- finally
- {
- logger.LogMessage($"Stopping client handler for client socket: [Remote EP: {clientEndPoint}]");
-
- if (activeClients.TryRemove(clientEndPoint, out Channel<SerialisedPacket> packetChannel))
- {
- packetChannel.Writer.Complete();
- logger.LogMessage(
- $"Shutting down packet channel for client socket: [Remote EP: {clientEndPoint}]");
- }
- else
- {
- logger.LogMessage(
- $"Couldn't shut down packet channel for client socket: [Remote EP: {clientEndPoint}]");
- }
- }
- }
-
- /// <inheritdoc />
- public UdpServer(TimeSpan networkOperationTimeout) : base(SocketType.Dgram, ProtocolType.Udp, networkOperationTimeout)
- {
- activeClients = new ConcurrentDictionary<EndPoint, Channel<SerialisedPacket>>();
- }
-
- /// <inheritdoc />
- public UdpServer() : this(DefaultNetworkOperationTimeout)
- {
- }
-
- /// <inheritdoc />
- public override async Task RunAsync(EndPoint localEndPoint)
- {
- bool bound = await TryBindAsync(localEndPoint, Timeout.InfiniteTimeSpan);
-
- if (!bound)
- {
- logger.LogError("Server socket was not bound successfully, shutting down server.");
- return;
- }
-
- OnServerStarted();
- runServer = true;
-
- while (runServer)
- {
- EndPoint nullEndPoint = new IPEndPoint(IPAddress.Any, 0);
- /*
- //(SerialisedPacket request, EndPoint remoteEndPoint) = await DoReceivePacketFromAsync(socket, nullEndPoint, SocketFlags.None, Timeout.InfiniteTimeSpan, serverShutdownCancellationToken);
- //EndPoint clientEndPoint = remoteEndPoint;
-
- if (request.Equals(SerialisedPacket.Null))
- {
- continue;
- }
-
- if (!activeClients.ContainsKey(clientEndPoint))
- {
- ClientHandlerArgs args = ClientHandlerArgs.ForUdpClientHandler(in clientEndPoint);
-
- activeClients.TryAdd(clientEndPoint, Channel.CreateUnbounded<SerialisedPacket>(clientChannelOptions));
-
- await Task.Factory.StartNew(DoHandleClientAsync, args, serverShutdownCancellationToken,
- TaskCreationOptions.LongRunning, TaskScheduler.Default);
- }
- */
-
- //await activeClients[clientEndPoint].Writer.WriteAsync(request);
- }
-
- OnServerStopped();
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Deprecated/UdpSocketOptions.cs b/NetSharp/NetSharp/Deprecated/UdpSocketOptions.cs
@@ -1,36 +0,0 @@
-using System.Net.Sockets;
-
-namespace NetSharp.Deprecated
-{
- /// <summary>
- /// Allows for manipulation of UDP socket options.
- /// </summary>
- public sealed class UdpSocketOptions : SocketOptions
- {
- /// <inheritdoc />
- public UdpSocketOptions(ref Socket socket) : base(ref socket)
- {
- }
-
- /// <inheritdoc />
- public override int HopLimit
- {
- get { return (int)managedSocket.GetSocketOption(SocketOptionLevel.Udp, SocketOptionName.HopLimit); }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.HopLimit, value); }
- }
-
- /// <inheritdoc />
- public override bool IsRoutingEnabled
- {
- get { return !(bool)managedSocket.GetSocketOption(SocketOptionLevel.Udp, SocketOptionName.DontRoute); }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.DontRoute, !value); }
- }
-
- /// <inheritdoc />
- public override bool UseLoopback
- {
- get { return (bool)managedSocket.GetSocketOption(SocketOptionLevel.Udp, SocketOptionName.UseLoopback); }
- set { managedSocket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.UseLoopback, value); }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/NetSharp.xml b/NetSharp/NetSharp/NetSharp.xml
@@ -4,2138 +4,23 @@
<name>NetSharp</name>
</assembly>
<members>
- <member name="T:NetSharp.Deprecated.Builtin.ConnectPacket">
- <summary>
- A simple connection request packet for the UDP protocol.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectPacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectPacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectPacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectPacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.ConnectResponsePacket">
- <summary>
- A response packet for the <see cref="T:NetSharp.Deprecated.Builtin.ConnectPacket"/>.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.Builtin.ConnectResponsePacket.RequestPacket">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectResponsePacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectResponsePacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectResponsePacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.ConnectResponsePacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.DataPacket">
- <summary>
- A simple data transfer packet, that allows for the transmission of an arbitrary number of frames.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Builtin.DataPacket.RequestBuffer">
- <summary>
- The data that should be transferred across the network.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataPacket.#ctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Builtin.DataPacket"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataPacket.#ctor(System.Memory{System.Byte})">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Builtin.DataPacket"/> class.
- </summary>
- <param name="buffer">The data that this request packet should contain.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataPacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataPacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataPacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataPacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.DataResponsePacket">
- <summary>
- A response packet for the <see cref="T:NetSharp.Deprecated.Builtin.DataPacket"/>.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Builtin.DataResponsePacket.ResponseBuffer">
- <summary>
- The data that should be transferred across the network.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataResponsePacket.#ctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Builtin.DataResponsePacket"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataResponsePacket.#ctor(System.Memory{System.Byte})">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Builtin.DataResponsePacket"/> class.
- </summary>
- <param name="buffer">The data that this response packet should contain.</param>
- </member>
- <member name="P:NetSharp.Deprecated.Builtin.DataResponsePacket.RequestPacket">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataResponsePacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataResponsePacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataResponsePacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DataResponsePacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.DisconnectPacket">
- <summary>
- A simple disconnect packet for the UDP protocol.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DisconnectPacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DisconnectPacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DisconnectPacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.DisconnectPacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.PingPacket">
- <summary>
- A simple ping request packet for heartbeat monitoring and RTT measurement.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingPacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingPacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingPacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingPacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.PingResponsePacket">
- <summary>
- A response packet for the <see cref="T:NetSharp.Deprecated.Builtin.PingPacket"/>.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.Builtin.PingResponsePacket.RequestPacket">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingResponsePacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingResponsePacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingResponsePacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.PingResponsePacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Builtin.SimpleDataPacket">
- <summary>
- A simple one-time-use data transfer packet, that allows for the transmission of an arbitrary number of frames.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Builtin.SimpleDataPacket.RequestBuffer">
- <summary>
- The data that should be transferred across the network.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.SimpleDataPacket.#ctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Builtin.SimpleDataPacket"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.SimpleDataPacket.#ctor(System.Memory{System.Byte})">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Builtin.SimpleDataPacket"/> class.
- </summary>
- <param name="buffer">The data that this request packet should contain.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.SimpleDataPacket.AfterDeserialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.SimpleDataPacket.BeforeSerialisation">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.SimpleDataPacket.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Builtin.SimpleDataPacket.Serialise">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.Client">
- <summary>
- Provides methods for connecting to and talking with a <see cref="T:NetSharp.Deprecated.IServer"/> instance.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Client.#ctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Client"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Client.Finalize">
- <summary>
- Destroys an instance of the <see cref="T:NetSharp.Deprecated.Client"/> class.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Client.socket">
- <summary>
- The <see cref="T:System.Net.Sockets.Socket"/> underlying the connection.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Client.socketOptions">
- <summary>
- Backing field for the <see cref="P:NetSharp.Deprecated.Client.SocketOptions"/> property.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Client.remoteEndPoint">
- <summary>
- The remote endpoint with which this client communicates.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Client.#ctor(System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Client"/> class.
- </summary>
- <param name="socketType">The socket type for the underlying socket.</param>
- <param name="protocolType">The protocol type for the underlying socket.</param>
- <param name="socketManager">The <see cref="!:Utils.Socket_Options.SocketOptions"/> manager to use.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Client.Dispose(System.Boolean)">
- <summary>
- Disposes of this <see cref="T:NetSharp.Deprecated.Client"/> instance.
- </summary>
- <param name="disposing">Whether this instance is being disposed.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Client.OnConnected(System.Net.EndPoint)">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.Client.Connected"/> event.
- </summary>
- <param name="endPoint">The remote endpoint with which a connection was made.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Client.OnDisconnected(System.Net.EndPoint)">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.Client.Disconnected"/> event.
- </summary>
- <param name="endPoint">The remote endpoint with which a connection was lost.</param>
- </member>
- <member name="E:NetSharp.Deprecated.Client.Connected">
- <inheritdoc />
- </member>
- <member name="E:NetSharp.Deprecated.Client.Disconnected">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.Client.SocketOptions">
- <summary>
- The configured socket options for the underlying connection.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Client.Disconnect">
- <summary>
- Disconnects the client from the remote endpoint.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Client.SendBytesAsync(System.Byte[],System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Client.SendBytesWithResponseAsync(System.Byte[],System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Client.SendComplexAsync``2(``0,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Client.SendSimpleAsync``1(``0,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Client.TryBindAsync(System.Net.IPAddress,System.Nullable{System.Int32},System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Client.TryConnectAsync(System.Net.IPAddress,System.Int32,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.ClientExtensions">
- <summary>
- Provides additional methods and functionality to the <see cref="T:NetSharp.Deprecated.Client"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendBytes(NetSharp.Deprecated.Client,System.Byte[])">
- <summary>
- Sends the given byte buffer to the connected remote endpoint. Blocks until the bytes are all sent, and does
- not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendBytes(NetSharp.Deprecated.Client,System.Byte[],System.TimeSpan)">
- <summary>
- Sends the given byte buffer to the connected remote endpoint. Blocks until the bytes are all sent, whilst
- observing a timeout of the given length.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- <param name="timeout">The timeout after which to cancel the transmission attempt.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendBytesAsync(NetSharp.Deprecated.Client,System.Byte[])">
- <summary>
- Sends the given byte buffer to the connected remote endpoint asynchronously. Does not block, and does not
- timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendBytesWithResponse(NetSharp.Deprecated.Client,System.Byte[])">
- <summary>
- Sends the given byte buffer to the connected remote endpoint and waits for the response. Blocks until the
- bytes are all sent and the response has been received, and does not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- <returns>The byte buffer that was received as a response.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendBytesWithResponse(NetSharp.Deprecated.Client,System.Byte[],System.TimeSpan)">
- <summary>
- Sends the given byte buffer to the connected remote endpoint and waits for the response. Blocks until the
- bytes are all sent and the response has been received, whilst observing a timeout of the given length.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- <param name="timeout">The timeout after which to cancel the transmission attempt.</param>
- <returns>The byte buffer that was received as a response.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendBytesWithResponseAsync(NetSharp.Deprecated.Client,System.Byte[])">
- <summary>
- Sends the given byte buffer to the connected remote endpoint and waits for the response asynchronously.
- Does not block, and does not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- <returns>The byte buffer received as a response to the sent buffer.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendComplex``2(NetSharp.Deprecated.Client,``0)">
- <summary>
- Sends the given request and listens for a response of the given type. Blocks until the response is received.
- Does not timeout.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <typeparam name="Rep">The type of response packet to receive.</typeparam>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="request">The request packet to send.</param>
- <returns>The received instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendComplex``2(NetSharp.Deprecated.Client,``0,System.TimeSpan)">
- <summary>
- Sends the given request and listens for a response of the given type. Blocks until the response is received.
- Cancels the operation if the given timeout is exceeded.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <typeparam name="Rep">The type of response packet to receive.</typeparam>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="request">The request packet to send.</param>
- <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- <returns>The received instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendComplexAsync``2(NetSharp.Deprecated.Client,``0)">
- <summary>
- Sends the given request and listens for a response of the given type asynchronously. Does not block. Does not timeout.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <typeparam name="Rep">The type of response packet to receive.</typeparam>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="request">The request packet to send.</param>
- <returns>The received instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendSimple``1(NetSharp.Deprecated.Client,``0)">
- <summary>
- Sends the given request without listening for a response, blocking until it is sent. Does not timeout.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="request">The request packet to send.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendSimple``1(NetSharp.Deprecated.Client,``0,System.TimeSpan)">
- <summary>
- Sends the given request without listening for a response, blocking until it is sent.
- Cancels the operation if the given timeout is exceeded.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="request">The request packet to send.</param>
- <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.SendSimpleAsync``1(NetSharp.Deprecated.Client,``0)">
- <summary>
- Sends the given request asynchronously without listening for a response, not blocking until it is sent.
- Does not timeout.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="request">The request packet to send.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.TryBind(NetSharp.Deprecated.Client,System.Net.IPAddress,System.Nullable{System.Int32})">
- <summary>
- Attempts to synchronously bind the underlying socket to the given local address and port. Blocks. Does not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.TryBind(NetSharp.Deprecated.Client,System.Net.IPAddress,System.Nullable{System.Int32},System.TimeSpan)">
- <summary>
- Attempts to synchronously bind the underlying socket to the given local address and port. Blocks.
- If the timeout is exceeded the binding attempt is aborted and the method returns false.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- <param name="timeout">The timeout within which to attempt the binding.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.TryBindAsync(NetSharp.Deprecated.Client,System.Net.IPAddress,System.Nullable{System.Int32})">
- <summary>
- Attempts to asynchronously bind the underlying socket to the given local address and port. Does not block.
- Does not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.TryConnect(NetSharp.Deprecated.Client,System.Net.IPAddress,System.Int32)">
- <summary>
- Attempts to connect to the remote <see cref="T:NetSharp.Deprecated.Server"/> at the given <see cref="T:System.Net.IPAddress"/> and over the
- given port. Does not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="remoteAddress">The remote IP address to connect to.</param>
- <param name="remotePort">The remote port to connect over.</param>
- <returns>Whether the connection was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.TryConnect(NetSharp.Deprecated.Client,System.Net.IPAddress,System.Int32,System.TimeSpan)">
- <summary>
- Attempts to connect to the remote <see cref="T:NetSharp.Deprecated.Server"/> at the given <see cref="T:System.Net.IPAddress"/> and over the
- given port. If the timeout is exceeded the connection attempt is aborted and the method returns false.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="remoteAddress">The remote IP address to connect to.</param>
- <param name="remotePort">The remote port to connect over.</param>
- <param name="timeout">The timeout within which to attempt the connection.</param>
- <returns>Whether the connection was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ClientExtensions.TryConnectAsync(NetSharp.Deprecated.Client,System.Net.IPAddress,System.Int32)">
- <summary>
- Attempts to connect asynchronously to the remote <see cref="T:NetSharp.Deprecated.Server"/> at the given <see cref="T:System.Net.IPAddress"/>
- and over the given port. Does not timeout.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="remoteAddress">The remote IP address to connect to.</param>
- <param name="remotePort">The remote port to connect over.</param>
- <returns>Whether the connection was successful or not.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.Connection">
- <summary>
- Encapsulates a connection capable of receiving packets and responding to them with registered packet handlers.
- </summary>
- <summary>
- Implements low-level network access on top of which the rest of the connection is built upon.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.incomingPacketPipeline">
- <summary>
- Pipeline to convert incoming byte buffers to <see cref="T:NetSharp.Deprecated.NetworkPacket"/> instances.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.loggerLockObject">
- <summary>
- Lock synchronisation object for the <see cref="F:NetSharp.Deprecated.Connection.logger"/> variable.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.outgoingPacketPipeline">
- <summary>
- Pipeline to convert outgoing <see cref="T:NetSharp.Deprecated.NetworkPacket"/> instances to a byte buffer for sending.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.ServerShutdownToken">
- <summary>
- Cancellation token which allows observing the shutdown of the server. It is set when <see cref="M:NetSharp.Deprecated.Connection.ShutdownServer"/> is called.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.logger">
- <summary>
- A logger object allowing for writing debug messages to an output stream.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.Finalize">
- <summary>
- Destroys a <see cref="T:NetSharp.Deprecated.Connection"/> class instance, freeing all managed resources.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.RunServerAsync">
- <summary>
- Makes the connection listen for incoming request packets, and handle them according to registered packet handler delegates.
- This work can be cancelled by calling <see cref="M:NetSharp.Deprecated.Connection.ShutdownServer"/>.
- </summary>
- <returns>The task representing the connection work.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.ShutdownServer">
- <summary>
- Shuts down the connection, and releases managed and unmanaged resources.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.AnyRemoteEndPoint">
- <summary>
- Represents any remote endpoint for datagram operations.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.Dispose(System.Boolean)">
- <summary>
- Disposes of the managed and unmanaged resources held by this instance.
- </summary>
- <param name="disposing">Whether this method is called by <see cref="M:NetSharp.Deprecated.Connection.Dispose"/> or by the finaliser.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.DoAcceptAsync(System.Net.Sockets.Socket,System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket accept operation.
- </summary>
- <param name="serverSocket">The socket which should be used to accept an incoming connection attempt.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- <returns>The accepted socket.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.DoConnectAsync(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket connect operation.
- </summary>
- <param name="socket">The socket which should asynchronously connect to the remote endpoint.</param>
- <param name="remoteEndPoint">The remote endpoint to which the socket should connect.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.DoDisconnectAsync(System.Net.Sockets.Socket,System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket disconnect operation.
- </summary>
- <param name="connectedSocket">The socket which should asynchronously disconnect from its remote endpoint.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.DoReceiveFromAsync(System.Net.Sockets.Socket,System.Net.EndPoint,System.Net.Sockets.SocketFlags,System.Memory{System.Byte},System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket receive operation.
- </summary>
- <param name="listenerSocket">The socket which should receive data from the remote endpoint.</param>
- <param name="remoteEndPoint">The remove endpoint from which data should be received.</param>
- <param name="socketFlags">The socket flags associated with the receive operation.</param>
- <param name="inputBuffer">The memory buffer into which received data will be stored.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- <returns>The result of the receive operation from the remote endpoint.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.DoSendToAsync(System.Net.Sockets.Socket,System.Net.EndPoint,System.Net.Sockets.SocketFlags,System.Memory{System.Byte},System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket send operation.
- </summary>
- <param name="transmitterSocket">The socket which should send the data to the remote endpoint.</param>
- <param name="remoteEndPoint">The remote endpoint to which data should be written.</param>
- <param name="socketFlags">The socket flags associated with the send operation.</param>
- <param name="outputBuffer">The data buffer which should be sent.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- <returns>The result of the send operation to the remote endpoint.</returns>
- </member>
- <member name="F:NetSharp.Deprecated.Connection.MaximumConnectionBacklog">
- <summary>
- The maximum number of stream connection that will be accepted.
- </summary>
- TODO change this to a configurable builder option
- </member>
- <member name="F:NetSharp.Deprecated.Connection.MaximumPacketBacklog">
- <summary>
- The maximum number of packets that will be stored before older packets start to be dropped.
- </summary>
- TODO change this to a configurable builder option
- </member>
- <member name="M:NetSharp.Deprecated.Connection.Dispose">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Connection.SetLoggingStream(System.IO.Stream,NetSharp.Deprecated.LogLevel)">
- <summary>
- Configures the logger to log messages to the given stream (or to <see cref="F:System.IO.Stream.Null"/> if <c>null</c>) and
- to only log messages that are of severity <paramref name="minimumLoggedSeverity"/> or higher.
- </summary>
- <param name="loggingStream">The stream to which messages will be logged.</param>
- <param name="minimumLoggedSeverity">The minimum severity a message must be to be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Connection.TryBindAsync(System.Net.EndPoint,System.TimeSpan)">
- <summary>
- Attempts to asynchronously bind the underlying socket to the given local endpoint. Does not block.
- If the timeout is exceeded the binding attempt is aborted and the method returns false.
- </summary>
- <param name="localEndPoint">The local endpoint to bind to.</param>
- <param name="timeout">The timeout within which to attempt the binding.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.ConnectionBuilder">
- <summary>
- Allows for configuring and subsequently building a <see cref="T:NetSharp.Deprecated.Connection"/> instance.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.ConnectionBuilder.IncomingPacketPipelineStageCount">
- <summary>
- The number of stages in the currently configured incoming packet pipeline.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.ConnectionBuilder.OutgoingPacketPipelineStageCount">
- <summary>
- The number of stages in the currently configured outgoing packet pipeline.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.Build">
- <summary>
- Returns a new <see cref="T:NetSharp.Deprecated.Connection"/> instance with the current configuration.
- </summary>
- <returns>The configured <see cref="T:NetSharp.Deprecated.Connection"/> instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.WithIncomingPipelineStage(System.Func{System.Memory{System.Byte},System.Memory{System.Byte}}@,System.Int32)">
- <summary>
- Adds an extra pipeline stage to the currently configured incoming packet pipeline, at the given index.
- </summary>
- <param name="transform">
- The transformation that should be applied when a packet passes through the pipeline.
- </param>
- <param name="index">The position in the pipeline at which to place the transform.</param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.WithLogging(NetSharp.Deprecated.ConnectionBuilder.LoggingSettings)">
- <summary>
- Sets the logging settings for the currently configured connection.
- </summary>
- <param name="settings">The logging settings to use.</param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.WithOutgoingPipelineStage(System.Func{System.Memory{System.Byte},System.Memory{System.Byte}}@,System.Int32)">
- <summary>
- Adds an extra pipeline stage to the currently configured outgoing packet pipeline, at the given index.
- </summary>
- <param name="transform">
- The transformation that should be applied when a packet passes through the pipeline.
- </param>
- <param name="index">The position in the pipeline at which to place the transform.</param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.WithPooling(NetSharp.Deprecated.ConnectionBuilder.PoolingSettings)">
- <summary>
- Sets the pooling settings for the currently configured connection.
- </summary>
- <param name="settings">The pooling settings to use.</param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.ConnectionBuilder.LoggingSettings">
- <summary>
- Holds settings for configuring a connection's logging.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.ConnectionBuilder.LoggingSettings.LoggingStream">
- <summary>
- The stream to which messages will be logged.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.ConnectionBuilder.LoggingSettings.MinimumLevel">
- <summary>
- The minimum severity that a log message must have to be recorded.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.LoggingSettings.#ctor(System.IO.Stream,NetSharp.Deprecated.LogLevel)">
- <summary>
- Initialises a new instance of the <see cref="F:NetSharp.Deprecated.ConnectionBuilder.LoggingSettings.LoggingStream"/> struct.
- </summary>
- <param name="stream">The stream to which messages will be logged..</param>
- <param name="minimumLevel">The minimum severity that a log message must have to be recorded.</param>
- </member>
- <member name="T:NetSharp.Deprecated.ConnectionBuilder.PoolingSettings">
- <summary>
- Holds settings for configuring a connection's buffer pooling.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.ConnectionBuilder.PoolingSettings.ObjectPoolSize">
- <summary>
- The number of objects that will be held in the object pools.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.ConnectionBuilder.PoolingSettings.PreallocateBuffers">
- <summary>
- Whether the buffers for receiving messages should be preallocated.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionBuilder.PoolingSettings.#ctor(System.Int32,System.Boolean)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.ConnectionBuilder.PoolingSettings"/> struct.
- </summary>
- <param name="poolSize">The number of objects that will be held in the object pools.</param>
- <param name="preallocateBuffers">Whether the buffers for receiving messages should be preallocated.</param>
- </member>
- <member name="T:NetSharp.Deprecated.ConnectionBuilderExtensions">
- <summary>
- Provides additional methods and functionality to the <see cref="T:NetSharp.Deprecated.ConnectionBuilder"/> class.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.ConnectionExtensions">
- <summary>
- Provides additional methods and functionality to the <see cref="T:NetSharp.Deprecated.Connection"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ConnectionExtensions.TryBind(NetSharp.Deprecated.Connection,System.Net.EndPoint,System.TimeSpan)">
- <summary>
- Attempts to synchronously bind the underlying socket to the given local endpoint. Blocks.
- If the timeout is exceeded the binding attempt is aborted and the method returns false.
- </summary>
- <param name="localEndPoint">The local endpoint to bind to.</param>
- <param name="timeout">The timeout within which to attempt the binding.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.Constants">
- <summary>
- Holds internal default configurations and constants.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Constants.DefaultPort">
- <summary>
- The default port over which a connection is made.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.DefaultSocketOptions">
- <summary>
- Allows for manipulation of socket options.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.DefaultSocketOptions.#ctor(System.Net.Sockets.Socket@)">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.DefaultSocketOptions.HopLimit">
- <inheritdoc />
- <exception cref="T:System.NotSupportedException">
- This property is not supported when using the default socket option manager.
- </exception>
- </member>
- <member name="P:NetSharp.Deprecated.DefaultSocketOptions.IsRoutingEnabled">
- <inheritdoc />
- <exception cref="T:System.NotSupportedException">
- This property is not supported when using the default socket option manager.
- </exception>
- </member>
- <member name="P:NetSharp.Deprecated.DefaultSocketOptions.UseLoopback">
- <inheritdoc />
- <exception cref="T:System.NotSupportedException">
- This property is not supported when using the default socket option manager.
- </exception>
- </member>
- <member name="T:NetSharp.Deprecated.IClient">
- <summary>
- Describes a client capable of asynchronous communication with an <see cref="T:NetSharp.Deprecated.IServer"/> connection.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.IClient.Connected">
- <summary>
- Signifies that a connection with the remote endpoint has been made.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.IClient.Disconnected">
- <summary>
- Signifies that the connection with the remote endpoint was severed.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.IClient.SendBytesAsync(System.Byte[],System.TimeSpan)">
- <summary>
- Sends the given byte buffer to the connected remote endpoint asynchronously. Does not block, and observes
- a timeout of the given length.
- timeout.
- </summary>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- <param name="timeout">The timeout after which to cancel the transmission attempt.</param>
- <returns>Whether the transmission attempt was successful.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IClient.SendBytesWithResponseAsync(System.Byte[],System.TimeSpan)">
- <summary>
- Sends the given byte buffer to the connected remote endpoint and waits for the response asynchronously.
- Does not block, and observes a timeout of the given length.
- timeout.
- </summary>
- <param name="buffer">The bytes that should be sent to the connected remote endpoint.</param>
- <param name="timeout">
- The timeout after which to cancel the transmission attempt. This timeout is reused by both the 'send' and
- 'receive' parts of the transmission attempt, such that the maximum timeout is equal to 2 times the given
- value.
- </param>
- <returns>The byte buffer received as a response to the sent buffer.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IClient.SendComplexAsync``2(``0,System.TimeSpan)">
- <summary>
- Sends the given request and listens for a response of the given type asynchronously. Does not block.
- Cancels the operation if the given timeout is exceeded
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <typeparam name="Rep">The type of response packet to receive.</typeparam>
- <param name="request">The request packet to send.</param>
- <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- <returns>The received instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IClient.SendSimpleAsync``1(``0,System.TimeSpan)">
- <summary>
- Sends the given request asynchronously without listening for a response, not blocking until it is sent.
- Cancels the operation if the given timeout is exceeded.
- </summary>
- <typeparam name="Req">The type of request packet to send.</typeparam>
- <param name="request">The request packet to send.</param>
- <param name="timeout">The timeout for which to wait for the operation to complete.</param>
- <returns>Whether the transmission attempt was successful.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IClient.TryBindAsync(System.Net.IPAddress,System.Nullable{System.Int32},System.TimeSpan)">
- <summary>
- Attempts to asynchronously bind the underlying socket to the given local address and port. Does not block.
- If the timeout is exceeded the binding attempt is aborted and the method returns false.
- </summary>
- <param name="localAddress">The local IP address to bind to. Null if any IP address will suffice.</param>
- <param name="localPort">The local port to bind to. Null if any port will suffice.</param>
- <param name="timeout">The timeout within which to attempt the binding.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IClient.TryConnectAsync(System.Net.IPAddress,System.Int32,System.TimeSpan)">
- <summary>
- Attempts to connect asynchronously to the remote <see cref="T:NetSharp.Deprecated.Server"/> at the given <see cref="T:System.Net.IPAddress"/>
- and over the given port. If the timeout is exceeded the connection attempt is aborted and the method returns false.
- </summary>
- <param name="remoteAddress">The remote IP address to connect to.</param>
- <param name="remotePort">The remote port to connect over.</param>
- <param name="timeout">The timeout within which to attempt the connection.</param>
- <returns>Whether the connection was successful or not.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.INetworkSerialisable">
- <summary>
- Describes an object that can be serialised to be sent across the network.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.INetworkSerialisable.Deserialise(System.ReadOnlyMemory{System.Byte})">
- <summary>
- Deserialises the object instance from a byte array.
- </summary>
- <param name="serialisedObject">The memory containing the serialised object instance.</param>
- </member>
- <member name="M:NetSharp.Deprecated.INetworkSerialisable.Serialise">
- <summary>
- Serialises the object instance into a byte array.
- </summary>
- <returns>The memory containing the serialised object instance.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.IPacket">
- <summary>
- Describes the methods and properties that every packet
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.IPacket.AfterDeserialisation">
- <summary>
- Allows for custom fields to be converted from their serialised format, after being received from the network.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.IPacket.BeforeSerialisation">
- <summary>
- Allows for custom fields to be converted into another format prior to being sent via the network.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.IPacketHandler">
- <summary>
- Describes a class capable of registering and deregistering packet handlers, and capable of
- handling incoming packets according to the currently registered packet handlers.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.IPacketHandler.TryDeregisterComplexPacketHandler``2(NetSharp.Deprecated.ComplexPacketHandler{``0,``1}@)">
- <summary>
- Attempts to deregister the complex packet handler delegate for all packets of the given type. If a handler
- method doesn't exist for the given packet type, <paramref name="oldHandlerDelegate"/> will be <c>default</c>.
- </summary>
- <typeparam name="Req">The type of request packet for which to deregister the handler delegate.</typeparam>
- <typeparam name="Rep">The type of response packet that is generated by the delegate method.</typeparam>
- <param name="oldHandlerDelegate">The old handler delegate method that was previously registered.</param>
- <returns>Whether the packet handler delegate was successfully deregistered.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IPacketHandler.TryDeregisterSimplePacketHandler``1(NetSharp.Deprecated.SimplePacketHandler{``0}@)">
- <summary>
- Attempts to deregister the simple packet handler delegate for all packets of the given type. If a handler
- method doesn't exist for the given packet type, <paramref name="oldHandlerDelegate"/> will be <c>default</c>.
- </summary>
- <typeparam name="Req">The type of request packet for which to deregister the handler delegate.</typeparam>
- <param name="oldHandlerDelegate">The old handler delegate method that was previously registered.</param>
- <returns>Whether the packet handler delegate was successfully deregistered.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IPacketHandler.TryRegisterComplexPacketHandler``2(NetSharp.Deprecated.ComplexPacketHandler{``0,``1})">
- <summary>
- Attempts to register a complex packet handler delegate for all packets of the given type. If a handler
- method already exists for the given packet type, it will be updated and replaced with the given one.
- </summary>
- <typeparam name="Req">The type of request packet for which to register the handler delegate.</typeparam>
- <typeparam name="Rep">The type of response packet that is generated by the delegate method.</typeparam>
- <param name="handlerDelegate">The delegate method to register as the complex packet handler.</param>
- <returns>Whether the packet handler delegate was successfully registered.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.IPacketHandler.TryRegisterSimplePacketHandler``1(NetSharp.Deprecated.SimplePacketHandler{``0})">
- <summary>
- Attempts to register a simple packet handler delegate for all packets of the given type. If a handler
- method already exists for the given packet type, it will be updated and replaced with the given one.
- </summary>
- <typeparam name="Req">The type of request packet for which to register the handler delegate.</typeparam>
- <param name="handlerDelegate">The delegate method to register as the simple packet handler.</param>
- <returns>Whether the packet handler delegate was successfully registered.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.IRequestPacket">
- <summary>
- Describes a request packet.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.IResponsePacket`1">
- <summary>
- Describes a response packet to a request packet.
- </summary>
- <typeparam name="TReq">The request packet that this type is a response to.</typeparam>
- </member>
- <member name="P:NetSharp.Deprecated.IResponsePacket`1.RequestPacket">
- <summary>
- The request packet that was handled with this response packet.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.IServer">
- <summary>
- Describes a server capable of asynchronously handling multiple <see cref="T:NetSharp.Deprecated.IClient"/> connections at once.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.IServer.ClientConnected">
- <summary>
- Signifies that a connection with a remote endpoint has been made.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.IServer.ClientDisconnected">
- <summary>
- Signifies that a connection with a remote endpoint has been lost.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.IServer.ServerStarted">
- <summary>
- Signifies that the server was started and clients will start being accepted.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.IServer.ServerStopped">
- <summary>
- Signifies that the server was stopped and clients will stop being accepted.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.IServer.RunAsync(System.Net.EndPoint)">
- <summary>
- Starts the server asynchronously and starts accepting client connections. Does not block.
- </summary>
- <param name="localEndPoint">The local endpoint to bind to.</param>
- </member>
- <member name="M:NetSharp.Deprecated.IServer.Shutdown">
- <summary>
- Shuts down the server.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.LogLevel">
- <summary>
- Specifies the severity level of a log message.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.LogLevel.Info">
- <summary>
- The logged message contains some information. Lowest severity.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.LogLevel.Warn">
- <summary>
- The logged message contains a warning. Higher severity.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.LogLevel.Error">
- <summary>
- The logged message contains details about an error. Higher severity.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.LogLevel.Exception">
- <summary>
- The logged message contains details about an exception. Highest severity.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.Logger">
- <summary>
- A simple logger capable of writing text to a stream.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Logger.loggingStream">
- <summary>
- The stream to which messages will be logged.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Logger.minimumSeverity">
- <summary>
- The minimum severity that log messages need to be logged to the underlying stream.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Logger.writer">
- <summary>
- The text writer we will use to log messages to the underlying stream.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.#ctor(System.IO.Stream,NetSharp.Deprecated.LogLevel)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Logger"/> struct.
- </summary>
- <param name="outputStream">The stream that the logger instance should log messages to.</param>
- <param name="minimumLogSeverity">The minimum log level that will be logged to the output stream.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.Dispose">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Logger.Log(System.String,System.Exception,NetSharp.Deprecated.LogLevel)">
- <summary>
- Logs a message to the underlying stream, along with the given exception and at the given severity.
- </summary>
- <param name="message">The message that should be logged.</param>
- <param name="exception">The exception that occurred (if any).</param>
- <param name="severity">The severity of the message that is being logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogAsync(System.String,System.Exception,NetSharp.Deprecated.LogLevel)">
- <summary>
- Logs a message asynchronously to the underlying stream, along with the given exception and at the given severity.
- </summary>
- <param name="message">The message that should be logged.</param>
- <param name="exception">The exception that occurred (if any).</param>
- <param name="severity">The severity of the message that is being logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogError(System.String)">
- <summary>
- Logs an error to the underlying stream, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Info"/>.
- </summary>
- <param name="message">The error that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogErrorAsync(System.String)">
- <summary>
- Logs an error to the underlying stream asynchronously, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Error"/>.
- </summary>
- <param name="message">The error that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogException(System.Exception)">
- <summary>
- Logs an exception to the underlying stream, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Exception"/>.
- </summary>
- <param name="exception">The exception that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogException(System.String,System.Exception)">
- <summary>
- Logs an exception to the underlying stream, along with a short debug message, with severity
- <see cref="F:NetSharp.Deprecated.LogLevel.Exception"/>.
- </summary>
- <param name="message">The debug message that should be logged with the exception.</param>
- <param name="exception">The exception that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogExceptionAsync(System.Exception)">
- <summary>
- Logs an exception to the underlying stream asynchronously, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Exception"/>.
- </summary>
- <param name="exception">The exception that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogExceptionAsync(System.String,System.Exception)">
- <summary>
- Logs an exception to the underlying stream asynchronously, along with a short debug message, with severity
- <see cref="F:NetSharp.Deprecated.LogLevel.Exception"/>.
- </summary>
- <param name="message">The debug message that should be logged with the exception.</param>
- <param name="exception">The exception that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogMessage(System.String)">
- <summary>
- Logs a message to the underlying stream, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Info"/>.
- </summary>
- <param name="message">The message that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogMessageAsync(System.String)">
- <summary>
- Logs a message to the underlying stream asynchronously, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Info"/>.
- </summary>
- <param name="message">The message that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogWarning(System.String)">
- <summary>
- Logs a warning to the underlying stream, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Info"/>.
- </summary>
- <param name="message">The warning that should be logged.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Logger.LogWarningAsync(System.String)">
- <summary>
- Logs a warning to the underlying stream asynchronously, with severity <see cref="F:NetSharp.Deprecated.LogLevel.Warn"/>.
- </summary>
- <param name="message">The warning that should be logged.</param>
- </member>
- <member name="T:NetSharp.Deprecated.NetworkErrorCode">
- <summary>
- Enumerates the possible error codes for network operations, being held in the packet.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkErrorCode.Ok">
- <summary>
- Signifies that there was no error during transmission.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkErrorCode.Error">
- <summary>
- A generic error occurred during packet transmission.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.NetworkPacket">
- <summary>
- Represents a low-level packet that is transmitted over the network.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.NetworkPacket.#ctor(System.ReadOnlyMemory{System.Byte},NetSharp.Deprecated.NetworkPacketHeader,NetSharp.Deprecated.NetworkPacketFooter)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.NetworkPacket"/> struct.
- </summary>
- <param name="data">The data that should be transmitted in the packet.</param>
- <param name="header">The header for the packet.</param>
- <param name="footer">The footer for the packet.</param>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacket.DataSegmentSize">
- <summary>
- The number of bytes allocated in each packet for user data.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacket.FooterSize">
- <summary>
- The number of bytes taken up in each packet by its footer.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacket.HeaderSize">
- <summary>
- The number of bytes taken up in each packet by its header.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacket.PacketSize">
- <summary>
- The size of each packet, including its header, footer, and data segment.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacket.DataBuffer">
- <summary>
- The data held in this packet.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.NetworkPacket.#ctor(System.ReadOnlyMemory{System.Byte},System.Int32,System.UInt32,NetSharp.Deprecated.NetworkErrorCode,System.Boolean)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.NetworkPacket"/> struct.
- </summary>
- <param name="data">The data that should be transmitted in the packet.</param>
- <param name="dataLength">The number of bytes that are held in the given data buffer.</param>
- <param name="type">The packet type.</param>
- <param name="errorCode">The error code associated with this transmission.</param>
- <param name="hasSucceedingPacket">Whether this packet has a succeeding packet in the packet chain.</param>
- </member>
- <member name="M:NetSharp.Deprecated.NetworkPacket.Deserialise(System.Memory{System.Byte})">
- <summary>
- Deserialises the given buffer into a packet instance.
- </summary>
- <param name="buffer">The byte buffer to serialise.</param>
- <returns>The deserialised packet instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.NetworkPacket.Serialise(NetSharp.Deprecated.NetworkPacket)">
- <summary>
- Serialises the given packet instance to a new byte buffer.
- </summary>
- <param name="instance">The packet instance to serialise.</param>
- <returns>The byte buffer that represents the packet instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.NetworkPacket.SerialiseToBuffer(System.Memory{System.Byte},NetSharp.Deprecated.NetworkPacket)">
- <summary>
- Serialises the given packet instance into the given byte buffer.
- </summary>
- <param name="buffer">
- The buffer to which the instance should be serialised. Must be at least of size <see cref="F:NetSharp.Deprecated.NetworkPacket.PacketSize"/>.
- </param>
- <param name="instance">The packet instance to serialise.</param>
- <exception cref="T:System.ArgumentException">Thrown if the given buffer is too small.</exception>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacketFooter.Size">
- <summary>
- The number of bytes taken up by a packet footer.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacketHeader.Size">
- <summary>
- The number of bytes taken up by a packet header.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacketHeader.DataLength">
- <summary>
- The number of bytes of data held in the packet.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacketHeader.ErrorCode">
- <summary>
- The error code for this packet.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.NetworkPacketHeader.Type">
- <summary>
- The packet type.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.PacketPipeline`3">
- <summary>
- Represents a pipeline of transformations that packets must undergo.
- </summary>
- <typeparam name="TInput">The type of packet the pipeline receives.</typeparam>
- <typeparam name="TIntermediate">The type of packet the pipeline internally handles.</typeparam>
- <typeparam name="TOutput">The type of packet the pipeline outputs.</typeparam>
- </member>
- <member name="M:NetSharp.Deprecated.PacketPipeline`3.ProcessPacket(`0)">
- <summary>
- Passes the given packet through the pipeline.
- </summary>
- <param name="inputPacket">The incoming packet.</param>
- <returns>The outgoing transformed packet.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.PacketPipelineStage`2">
- <summary>
- Represents a single transformation applied to a packet traveling through the pipeline.
- </summary>
- <typeparam name="TInput">The type the transformation takes as input.</typeparam>
- <typeparam name="TOutput">The type the transformation produces as output.</typeparam>
- </member>
- <member name="T:NetSharp.Deprecated.PacketPipelineBuilder`3">
- <summary>
- Allows for configuring and subsequently building a <see cref="T:NetSharp.Deprecated.PacketPipeline`3"/> instance.
- </summary>
- <typeparam name="TInput">The type of packet that will be submitted to the pipeline.</typeparam>
- <typeparam name="TIntermediate">The type of packet that will be handled internally by the pipeline.</typeparam>
- <typeparam name="TOutput">The type of packet that will be requested from the pipeline.</typeparam>
- </member>
- <member name="M:NetSharp.Deprecated.PacketPipelineBuilder`3.Build">
- <summary>
- Returns the currently configured <see cref="T:NetSharp.Deprecated.PacketPipeline`3"/> instance.
- </summary>
- <returns>The configured <see cref="T:NetSharp.Deprecated.PacketPipeline`3"/> instance.</returns>
- <exception cref="T:System.ArgumentNullException">
- Thrown when either <see cref="M:NetSharp.Deprecated.PacketPipelineBuilder`3.WithInputStage(System.Func{`0,`1}@)"/> or <see cref="M:NetSharp.Deprecated.PacketPipelineBuilder`3.WithOutputStage(System.Func{`1,`2}@)"/> have not been called.
- </exception>
- </member>
- <member name="M:NetSharp.Deprecated.PacketPipelineBuilder`3.WithInputStage(System.Func{`0,`1}@)">
- <summary>
- Configures the input stage for the pipeline.
- </summary>
- <param name="stage">
- The transformation that should be applied to incoming packets, to convert them from the <typeparamref name="TInput"/>
- type to the <typeparamref name="TIntermediate"/> type that the pipeline handles internally.
- </param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketPipelineBuilder`3.WithIntermediateStage(System.Func{`1,`1}@)">
- <summary>
- Adds the given intermediate stage to the pipeline.
- </summary>
- <param name="stage">
- The transformation that should be applied to packets traveling through the pipeline.
- </param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketPipelineBuilder`3.WithOutputStage(System.Func{`1,`2}@)">
- <summary>
- Configures the output stage for the pipeline.
- </summary>
- <param name="stage">
- The transformation that should be applied to outgoing packets, to convert them from the
- <typeparamref name="TIntermediate"/> type used internally to the <typeparamref name="TOutput"/> type.
- </param>
- <returns>The builder instance for further configuration.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.PacketRegistry">
- <summary>
- Provides method of registering request packets and their relevant response packets, as well as mapping their ids.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.PacketRegistry.AutomaticPacketTypeIdStartPoint">
- <summary>
- The start id for automatically generated packet type ids. Any custom packet type ids lower than this value
- that come from external assemblies will be incremented by this value, to ensure that there are no clashes.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.PacketRegistry.currentAutomaticPacketTypeIdCounterLockObject">
- <summary>
- The lock object for synchronising access to the <see cref="F:NetSharp.Deprecated.PacketRegistry.currentAutomaticPacketTypeIdCounter"/> field.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.PacketRegistry.idToPacketTypeMap">
- <summary>
- Maps a packet type id to its relevant packet type, and vice-versa.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.PacketRegistry.LibraryAssembly">
- <summary>
- The assembly that represents the library, where all of the builtin packets are defined.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.PacketRegistry.requestToResponseMap">
- <summary>
- Maps a request packet to its relevant response packet, and vice-versa.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.PacketRegistry.currentAutomaticPacketTypeIdCounter">
- <summary>
- The current id for registered packets.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetNewPacketTypeId(System.Type)">
- <summary>
- Fetches the packet type id of the given packet type. If the packet type is declared outside of the library
- assembly, then its value is incremented by the <see cref="F:NetSharp.Deprecated.PacketRegistry.AutomaticPacketTypeIdStartPoint"/> value. This ensure that
- there are no clashes between the packet type ids of packets declared in the library and external packets.
- </summary>
- <param name="packetType">The packet type whose id should be fetched.</param>
- <returns>The id of the given packet type.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.DeregisterPacketType(System.Type,System.Type)">
- <summary>
- Deregisters the given packet type from the registry.
- </summary>
- <param name="requestPacketType">The request packet type to deregister, if it is registered.</param>
- <param name="responsePacketType">The response packet associated with the request packet.</param>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.DeregisterPacketTypes(System.Collections.Generic.Dictionary{System.Type,System.Type})">
- <summary>
- Deregisters the given packet types from the registry.
- </summary>
- <param name="requestToResponsePacketTypeMap">The list of packet types to deregister, if they are registered.</param>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetPacketId(System.Type)">
- <summary>
- Returns the packet type id associated with the given packet type.
- </summary>
- <param name="packetType">The packet type whose id to fetch.</param>
- <returns>The id of the packet type given.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetPacketId``1">
- <summary>
- Returns the packet type id associated with the given packet type.
- </summary>
- <typeparam name="TPacket">The packet type whose id to fetch.</typeparam>
- <returns>The id of the packet type given.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetPacketType(System.UInt32)">
- <summary>
- Returns the packet type associated with the given id.
- </summary>
- <param name="packetTypeId">The packet id whose mapped type to fetch.</param>
- <returns>The packet type mapped by the given id.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetRequestPacketType``1">
- <summary>
- Returns the type of request packet mapped by the given response packet type.
- </summary>
- <typeparam name="TResponse">The response packet type whose request packet type to fetch.</typeparam>
- <returns>The request packet type, <c>null</c> if no type is mapped.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetRequestPacketType(System.Type)">
- <summary>
- Returns the type of request packet mapped by the given response packet type.
- </summary>
- <param name="responsePacketType">The response packet type whose request packet type to fetch.</param>
- <returns>The request packet type, <c>null</c> if no type is mapped.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetResponsePacketType``1">
- <summary>
- Returns the type of response packet mapped by the given request packet type.
- </summary>
- <typeparam name="TRequest">The request packet type whose response packet type to fetch.</typeparam>
- <returns>The response packet type, <c>null</c> if no type is mapped.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.GetResponsePacketType(System.Type)">
- <summary>
- Returns the type of response packet mapped by the given request packet type.
- </summary>
- <param name="requestPacketType">The request packet type whose response packet type to fetch.</param>
- <returns>The response packet type, <c>null</c> if no type is mapped.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.RegisterPacketSourceAssemblies(System.Reflection.Assembly[])">
- <summary>
- Rebuilds the packet registry, by registering every <see cref="T:NetSharp.Deprecated.IPacket"/> inheritor in the given assemblies.
- </summary>
- <param name="packetSourceAssemblies">
- The assemblies from which the packet types to register are sourced.
- </param>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.RegisterPacketSourceAssembly(System.Reflection.Assembly)">
- <summary>
- Registers all the <see cref="T:NetSharp.Deprecated.IPacket"/> implementors in the given assembly.
- </summary>
- <param name="packetSourceAssembly">The assembly whose packet types to register.</param>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.RegisterPacketType(System.Type,System.Type)">
- <summary>
- Registers the given packet type to the registry.
- </summary>
- <param name="requestPacketType">The request packet type to register, if it is not registered.</param>
- <param name="responsePacketType">The response packet associated with the request packet.</param>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.RegisterPacketTypes(System.Collections.Generic.Dictionary{System.Type,System.Type})">
- <summary>
- Registers the given packet types to the registry.
- </summary>
- <param name="requestToResponsePacketTypeMap">
- The dictionary mapping the request packet types to register, to their relevant response packet types.
- The response packet type can be null; then the request packet type is treated as a 'simple' packet.
- </param>
- </member>
- <member name="M:NetSharp.Deprecated.PacketRegistry.#cctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.PacketRegistry"/> class.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.PacketTypeIdAttribute">
- <summary>
- Allows the placing of a custom packet type on a class or struct. This is used if the class or struct
- inherits from <see cref="T:NetSharp.Deprecated.IRequestPacket"/> or <see cref="T:NetSharp.Deprecated.IResponsePacket`1"/>.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.PacketTypeIdAttribute.#ctor(System.UInt32)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.PacketTypeIdAttribute"/> attribute.
- </summary>
- <param name="type">The custom type id that the decorated packet type should have.</param>
- </member>
- <member name="P:NetSharp.Deprecated.PacketTypeIdAttribute.Id">
- <summary>
- The custom type id that the decorated packet type should have. This overrides the automatically generated id.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.RemoteSocketClient.Dispose">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.RemoteSocketClient.Dispose(System.Boolean)">
- <summary>
- Implementation of dispose pattern.
- </summary>
- <param name="disposing">
- Whether this method is being called by the object finalizer, or by the <see cref="M:NetSharp.Deprecated.RemoteSocketClient.Dispose"/> method.
- </param>
- </member>
- <member name="M:NetSharp.Deprecated.SerialisedPacket.From``1(``0)">
- <summary>
- Serialises the given serialisable packet instance and returns the <see cref="T:NetSharp.Deprecated.SerialisedPacket"/> instance
- that was generated. This method invokes <see cref="M:NetSharp.Deprecated.IPacket.BeforeSerialisation"/>.
- </summary>
- <typeparam name="T">The packet type that will be serialised.</typeparam>
- <param name="serialisable">The packet instance that should be serialised.</param>
- <returns>The serialised instance.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.SerialisedPacket.To``1(NetSharp.Deprecated.SerialisedPacket@)">
- <summary>
- Deserialises and returns a packet instance of the given type from the <see cref="T:NetSharp.Deprecated.SerialisedPacket"/> instance
- that was given. This method invokes <see cref="M:NetSharp.Deprecated.IPacket.AfterDeserialisation"/>.
- </summary>
- <typeparam name="T">The packet type to which the packet should be deserialised.</typeparam>
- <param name="instance">The serialised packet instance that should be deserialised.</param>
- <returns>The deserialised instance.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.ComplexPacketHandler`2">
- <summary>
- Represents a method that receives a request packet of the given type (<typeparamref name="TReq"/>) and
- handles the request, returning a response packet of the given type (<typeparamref name="TRep"/>).
- </summary>
- <typeparam name="TReq">The type of request packet handled by this delegate method.</typeparam>
- <typeparam name="TRep">The type of response packet returned by this delegate method.</typeparam>
- <param name="requestPacket">The request packet that should be handled by this delegate method.</param>
- <param name="remoteEndPoint">The remote endpoint from which the request originated.</param>
- <returns>The response packet to send back to the remote endpoint from which the request originated.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.SimplePacketHandler`1">
- <summary>
- Represents a method that receives a simple request packet of the given type (<typeparamref name="TReq"/>) and
- handles the request, not returning any response packets.
- </summary>
- <typeparam name="TReq">The type of request packet handled by this delegate method.</typeparam>
- <param name="requestPacket">The request packet that should be handled by this delegate method.</param>
- <param name="remoteEndPoint">The remote endpoint from which the request originated.</param>
- </member>
- <member name="T:NetSharp.Deprecated.Server">
- <summary>
- Provides methods for handling connected <see cref="T:NetSharp.Deprecated.IClient"/> instances.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.complexPacketHandlers">
- <summary>
- Maps a packet type id to the complex packet handler for that packet type.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.requestPacketDeserialisers">
- <summary>
- Maps a packet type id to the raw packet deserialiser that deserialises raw packets to
- <see cref="T:NetSharp.Deprecated.IRequestPacket"/> implementors.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.serverShutdownCancellationTokenSource">
- <summary>
- Cancellation token source to stop handling client sockets when the server should be shut down.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.simplePacketHandlers">
- <summary>
- Maps a packet type id to the simple packet handler for that packet type.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.#ctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Server"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.Finalize">
- <summary>
- Destroys an instance of the <see cref="T:NetSharp.Deprecated.Server"/> class.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.Server.RawRequestPacketDeserialiser">
- <summary>
- Represents a method that receives a raw packet, and deserialises it into an <see cref="T:NetSharp.Deprecated.IRequestPacket"/> implementor.
- </summary>
- <param name="rawPacket">The raw packet that was received from the network.</param>
- <returns>The deserialised instance of the packet.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Server.RegisterInternalPacketHandlers">
- <summary>
- Registers packet handlers for every internal library packet.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.PendingConnectionBacklog">
- <summary>
- The maximum number of connections that are allowed in the connection backlog.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.DefaultNetworkOperationTimeout">
- <summary>
- The default timeout value for all network operations.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.serverShutdownCancellationToken">
- <summary>
- The cancellation token that will be set when the server must be shut down.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.socket">
- <summary>
- The <see cref="T:System.Net.Sockets.Socket"/> underlying the connection.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.socketOptions">
- <summary>
- Backing field for the <see cref="P:NetSharp.Deprecated.Server.SocketOptions"/> property.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.runServer">
- <summary>
- Whether the server should be ran.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.#ctor(System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Server"/> class.
- </summary>
- <param name="socketType">The socket type for the underlying socket.</param>
- <param name="protocolType">The protocol type for the underlying socket.</param>
- <param name="socketManager">The <see cref="!:Utils.Socket_Options.SocketOptions"/> implementation to use.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.#ctor(System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType,System.TimeSpan)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Server"/> class.
- </summary>
- <param name="socketType">The socket type for the underlying socket.</param>
- <param name="protocolType">The protocol type for the underlying socket.</param>
- <param name="socketManager">The <see cref="!:Utils.Socket_Options.SocketOptions"/> manager to use.</param>
- <param name="networkOperationTimeout">The timeout value for send and receive operations over the network.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.DeserialiseRequestPacket(System.UInt32,NetSharp.Deprecated.SerialisedPacket@)">
- <summary>
- Deserialises the given <see cref="T:NetSharp.Deprecated.NetworkPacket"/> struct into an <see cref="T:NetSharp.Deprecated.IRequestPacket"/> implementor.
- </summary>
- <param name="packetType">The type id of packet that we should deserialise to.</param>
- <param name="rawRequestPacket">The packet that should be deserialised.</param>
- <returns>The deserialised packet instance, cast to the <see cref="T:NetSharp.Deprecated.IRequestPacket"/> interface.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Server.Dispose(System.Boolean)">
- <summary>
- Disposes of this <see cref="T:NetSharp.Deprecated.Server"/> instance.
- </summary>
- <param name="disposing">Whether this instance is being disposed.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.DoHandleClientAsync(System.Object)">
- <summary>
- Provides a task that represents the handling of a client. Calls the abstract <see cref="M:NetSharp.Deprecated.Server.HandleClientAsync(NetSharp.Deprecated.Server.ClientHandlerArgs,System.Threading.CancellationToken)"/> method.
- </summary>
- <param name="clientHandlerArgsObj">The object representing the passed <see cref="T:NetSharp.Deprecated.Server.ClientHandlerArgs"/> instance.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.HandleClientAsync(NetSharp.Deprecated.Server.ClientHandlerArgs,System.Threading.CancellationToken)">
- <summary>
- Handles a client asynchronously.
- </summary>
- <param name="args">The client handler arguments that should be passed to the client handler.</param>
- <param name="cancellationToken">Cancellation token set when the server is shutting down.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.HandleRequestPacket(System.UInt32,NetSharp.Deprecated.IRequestPacket@,System.Net.EndPoint@)">
- <summary>
- Handles the given request packet with a registered packet handler. In this case, a complex packet handler
- will override any registered simple packet handlers.
- </summary>
- <param name="packetType">The type id of the packet that we should handle.</param>
- <param name="requestPacket">The packet instance that should be handled.</param>
- <param name="remoteEndPoint">The remote endpoint from which the request packet originated.</param>
- <returns>The response packet that should be sent back to the remote endpoint.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Server.OnClientConnected(System.Net.EndPoint)">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.Server.ClientConnected"/> event.
- </summary>
- <param name="remoteEndPoint">The remote endpoint with which a connection was made.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.OnClientDisconnected(System.Net.EndPoint)">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.Server.ClientDisconnected"/> event.
- </summary>
- <param name="remoteEndPoint">The remote endpoint with which a connection was lost.</param>
- </member>
- <member name="M:NetSharp.Deprecated.Server.OnServerStarted">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.Server.ServerStarted"/> event.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.OnServerStopped">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.Server.ServerStopped"/> event.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.TryBind(System.Net.EndPoint,System.TimeSpan)">
- <summary>
- Attempts to synchronously bind the underlying socket to the given local endpoint. Blocks.
- If the timeout is exceeded the binding attempt is aborted and the method returns false.
- </summary>
- <param name="localEndPoint">The local endpoint to bind to.</param>
- <param name="timeout">The timeout within which to attempt the binding.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Server.TryBindAsync(System.Net.EndPoint,System.TimeSpan)">
- <summary>
- Attempts to asynchronously bind the underlying socket to the given local endpoint. Does not block.
- If the timeout is exceeded the binding attempt is aborted and the method returns false.
- </summary>
- <param name="localEndPoint">The local endpoint to bind to.</param>
- <param name="timeout">The timeout within which to attempt the binding.</param>
- <returns>Whether the binding was successful or not.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.Server.ClientHandlerArgs">
- <summary>
- Holds information about the arguments passed to every client handler task.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.ClientHandlerArgs.#ctor(System.Net.EndPoint,System.Net.Sockets.Socket)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.Server.ClientHandlerArgs"/> struct.
- </summary>
- <param name="remoteEndPoint">The remote endpoint of the client that should be handled.</param>
- <param name="handlerSocket">The handler socket of the client that should be handled.</param>
- </member>
- <member name="F:NetSharp.Deprecated.Server.ClientHandlerArgs.ClientEndPoint">
- <summary>
- The remote endpoint for the client being handled.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.Server.ClientHandlerArgs.ClientSocket">
- <summary>
- The client handler socket for the client being handled. Is only set if using TCP.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.ClientHandlerArgs.ForTcpClientHandler(System.Net.Sockets.Socket@)">
- <summary>
- Constructs a new instance of the <see cref="T:NetSharp.Deprecated.Server.ClientHandlerArgs"/> for a TCP client.
- </summary>
- <returns>A new instance of the <see cref="T:NetSharp.Deprecated.Server.ClientHandlerArgs"/>, setup for a TCP client.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.Server.ClientHandlerArgs.ForUdpClientHandler(System.Net.EndPoint@)">
- <summary>
- Constructs a new instance of the <see cref="T:NetSharp.Deprecated.Server.ClientHandlerArgs"/> for a UDP client.
- </summary>
- <returns>A new instance of the <see cref="T:NetSharp.Deprecated.Server.ClientHandlerArgs"/>, setup for a UDP client.</returns>
- </member>
- <member name="E:NetSharp.Deprecated.Server.ClientConnected">
- <summary>
- Signifies that a connection with a remote endpoint has been made.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.Server.ClientDisconnected">
- <summary>
- Signifies that a connection with a remote endpoint has been lost.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.Server.ServerStarted">
- <summary>
- Signifies that the server was started and clients will start being accepted.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.Server.ServerStopped">
- <summary>
- Signifies that the server was stopped and clients will stop being accepted.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.Server.NetworkOperationTimeout">
- <summary>
- The timeout value for network operations such as sending bytes or receiving bytes over the network.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.Server.SocketOptions">
- <summary>
- The configured socket options for the underlying connection.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.Server.RunAsync(System.Net.EndPoint)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Server.Shutdown">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Server.TryDeregisterComplexPacketHandler``2(NetSharp.Deprecated.ComplexPacketHandler{``0,``1}@)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Server.TryDeregisterSimplePacketHandler``1(NetSharp.Deprecated.SimplePacketHandler{``0}@)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Server.TryRegisterComplexPacketHandler``2(NetSharp.Deprecated.ComplexPacketHandler{``0,``1})">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.Server.TryRegisterSimplePacketHandler``1(NetSharp.Deprecated.SimplePacketHandler{``0})">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.ServerClientConnection">
- <summary>
- Base class for connections, holding methods shared between the <see cref="T:NetSharp.Deprecated.Client"/> and <see cref="T:NetSharp.Deprecated.Server"/> classes.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.ServerClientConnection.logger">
- <summary>
- The logger to which the server can log messages.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ServerClientConnection.#ctor">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.ServerClientConnection"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ServerClientConnection.Dispose(System.Boolean)">
- <summary>
- Disposes of this <see cref="T:NetSharp.Deprecated.ServerClientConnection"/> instance.
- </summary>
- <param name="disposing">Whether this instance is being disposed.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ServerClientConnection.OnBytesReceived(System.Net.EndPoint,System.Int32)">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.ServerClientConnection.BytesReceived"/> event.
- </summary>
- <param name="remoteEndPoint">The remote endpoint from which the bytes were received.</param>
- <param name="bytesReceived">The number of bytes that were received from the remote endpoint.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ServerClientConnection.OnBytesSent(System.Net.EndPoint,System.Int32)">
- <summary>
- Invokes the <see cref="E:NetSharp.Deprecated.ServerClientConnection.BytesSent"/> event.
- </summary>
- <param name="remoteEndPoint">The remote endpoint to which the bytes were sent.</param>
- <param name="bytesSent">The number of bytes that were sent to the remote endpoint.</param>
- </member>
- <member name="E:NetSharp.Deprecated.ServerClientConnection.BytesReceived">
- <summary>
- Signifies that some data has been received from the remote endpoint.
- </summary>
- </member>
- <member name="E:NetSharp.Deprecated.ServerClientConnection.BytesSent">
- <summary>
- Signifies that some data was sent to the remote endpoint.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ServerClientConnection.ChangeLoggingStream(System.IO.Stream,NetSharp.Deprecated.LogLevel)">
- <summary>
- Makes the client log to the given stream.
- </summary>
- <param name="loggingStream">The stream that new messages should be logged to.</param>
- <param name="minimumMessageSeverityLevel">
- The minimum severity level that new messages must have to be logged to the stream.
- </param>
- </member>
- <member name="M:NetSharp.Deprecated.ServerClientConnection.Dispose">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.ServerExtensions">
- <summary>
- Provides additional methods and functionality to the <see cref="T:NetSharp.Deprecated.Server"/> class.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.ServerExtensions.Run(NetSharp.Deprecated.Server,System.Net.IPAddress,System.Int32)">
- <summary>
- Starts the server synchronously and starts accepting client connections. Blocks.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to.</param>
- <param name="localPort">The local port to bind to.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ServerExtensions.Run(NetSharp.Deprecated.Server,System.Net.IPAddress)">
- <summary>
- Starts the server synchronously and starts accepting client connections. Blocks. Uses the default connection port.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ServerExtensions.RunAsync(NetSharp.Deprecated.Server,System.Net.IPAddress)">
- <summary>
- Starts the server asynchronously and starts accepting client connections. Does not block. Uses the default
- connection port.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to.</param>
- </member>
- <member name="M:NetSharp.Deprecated.ServerExtensions.RunAsync(NetSharp.Deprecated.Server,System.Net.IPAddress,System.Int32)">
- <summary>
- Starts the server asynchronously and starts accepting client connections. Does not block.
- </summary>
- <param name="instance">The instance on which this extension method should be called.</param>
- <param name="localAddress">The local IP address to bind to.</param>
- <param name="localPort">The local port to bind to.</param>
- </member>
- <member name="T:NetSharp.Deprecated.SocketAcceptor">
- <summary>
- Helper class providing awaitable wrappers around asynchronous Accept, Connect, and Disconnect operations.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.SocketAcceptor.AcceptAsync(System.Net.Sockets.Socket,System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket accept operation.
- </summary>
- <param name="socket">The socket which should be used to accept an incoming connection attempt.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- <returns>The accepted socket.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.SocketAcceptor.ConnectAsync(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket connect operation.
- </summary>
- <param name="socket">The socket which should asynchronously connect to the remote endpoint.</param>
- <param name="remoteEndPoint">The remote endpoint to which the socket should connect.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- </member>
- <member name="M:NetSharp.Deprecated.SocketAcceptor.DisconnectAsync(System.Net.Sockets.Socket,System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket disconnect operation.
- </summary>
- <param name="socket">The socket which should asynchronously disconnect from its remote endpoint.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- </member>
- <member name="M:NetSharp.Deprecated.SocketClient.Finalize">
- <summary>
- Destroys a socket client instance.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.SocketClient.Dispose(System.Boolean)">
- <summary>
- Implementation of dispose pattern.
- </summary>
- <param name="disposing">
- Whether this method is being called by the object finalizer, or by the <see cref="M:NetSharp.Deprecated.SocketClient.Dispose"/> method.
- </param>
- </member>
- <member name="M:NetSharp.Deprecated.SocketClient.Dispose">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.SocketOperations">
- <summary>
- Provides helper awaitable functions for wrapping the <see cref="T:System.Net.Sockets.SocketAsyncEventArgs"/> pattern.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.SocketOptions">
- <summary>
- Allows for manipulation of socket options.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.SocketOptions.managedSocket">
- <summary>
- The <see cref="T:System.Net.Sockets.Socket"/> instance whose settings are being managed.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.SocketOptions.#ctor(System.Net.Sockets.Socket@)">
- <summary>
- Initialises a new instance of the <see cref="T:NetSharp.Deprecated.SocketOptions"/> class.
- </summary>
- <param name="socket">The <see cref="T:System.Net.Sockets.Socket"/> instance whose options should be managed.</param>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.DualMode">
- <summary>
- Whether this <see cref="T:System.Net.Sockets.Socket"/> can operate in dual IPv4 / IPv6 mode.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.ForceFlush">
- <summary>
- Whether sending a packet flushes underlying <see cref="T:System.Net.Sockets.NetworkStream"/>.
- </summary>
- <remarks>
- This value is only used in a <see cref="T:System.Net.Sockets.TcpClient"/> instance, which uses a <see cref="T:System.Net.Sockets.NetworkStream"/>
- to send and receive data. A <see cref="T:System.Net.Sockets.UdpClient"/> is unaffected by this value.
- </remarks>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.Fragment">
- <summary>
- Whether this <see cref="T:System.Net.Sockets.Socket"/> is allowed to fragment frames that are too large to send in one go.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.HopLimit">
- <summary>
- The hop limit for packets sent by this <see cref="T:System.Net.Sockets.Socket"/>. Comparable to IPv4s TTL (Time To Live).
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.IsChecksumEnabled">
- <summary>
- Whether a checksum should be created for each UDP packet sent.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.IsRoutingEnabled">
- <summary>
- Whether the packet should be sent directly to its destination or allowed to be routed through multiple destinations
- first.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.LocalEndPoint">
- <summary>
- The local <see cref="T:System.Net.EndPoint"/> for the <see cref="F:NetSharp.Deprecated.SocketOptions.managedSocket"/>.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.LocalIPEndPoint">
- <summary>
- The local <see cref="T:System.Net.IPEndPoint"/> for this <see cref="T:System.Net.Sockets.Socket"/> instance.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.RemoteEndPoint">
- <summary>
- The remote <see cref="T:System.Net.EndPoint"/> for the <see cref="F:NetSharp.Deprecated.SocketOptions.managedSocket"/>.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.RemoteIPEndPoint">
- <summary>
- The remote <see cref="T:System.Net.IPEndPoint"/> that this <see cref="T:System.Net.Sockets.Socket"/> instance communicates with.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.Ttl">
- <summary>
- The 'Time To Live' for this <see cref="T:System.Net.Sockets.Socket"/>.
- </summary>
- </member>
- <member name="P:NetSharp.Deprecated.SocketOptions.UseLoopback">
- <summary>
- Whether this <see cref="T:System.Net.Sockets.Socket"/> should use a loopback address and bypass hardware.
- </summary>
- </member>
- <member name="T:NetSharp.Deprecated.SocketReader">
- <summary>
- Helper class providing awaitable wrappers around asynchronous Receive and ReceiveFrom operations.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.SocketReader.ReceiveFromAsync(System.Net.Sockets.Socket,System.Net.EndPoint,System.Net.Sockets.SocketFlags,System.Memory{System.Byte},System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket receive operation.
- </summary>
- <param name="socket">The socket which should receive data from the remote endpoint.</param>
- <param name="remoteEndPoint">The remove endpoint from which data should be received.</param>
- <param name="socketFlags">The socket flags associated with the receive operation.</param>
- <param name="inputBuffer">The memory buffer into which received data will be stored.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- <returns>The result of the receive operation.</returns>
- </member>
- <member name="M:NetSharp.Deprecated.SocketServer.Finalize">
- <summary>
- Destroys a socket server instance.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.SocketServer.listenerSocket">
- <summary>
- The socket which should be used to listen for incoming data and to send outgoing data.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.SocketServer.Dispose(System.Boolean)">
- <summary>
- Implementation of dispose pattern.
- </summary>
- <param name="disposing">
- Whether this method is being called by the object finalizer, or by the <see cref="M:NetSharp.Deprecated.SocketServer.Dispose"/> method.
- </param>
- </member>
- <member name="M:NetSharp.Deprecated.SocketServer.Dispose">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.SocketWriter">
- <summary>
- Helper class providing awaitable wrappers around asynchronous Send and SendTo operations.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.SocketWriter.SendToAsync(System.Net.Sockets.Socket,System.Net.EndPoint,System.Net.Sockets.SocketFlags,System.Memory{System.Byte},System.Threading.CancellationToken)">
- <summary>
- Provides an awaitable wrapper around an asynchronous socket send operation.
- </summary>
- <param name="socket">The socket which should send the data to the remote endpoint.</param>
- <param name="remoteEndPoint">The remote endpoint to which data should be written.</param>
- <param name="socketFlags">The socket flags associated with the send operation.</param>
- <param name="outputBuffer">The data buffer which should be sent.</param>
- <param name="cancellationToken">The cancellation token to observe for the operation.</param>
- <returns>The number of bytes of data which were written to the remote endpoint.</returns>
- </member>
- <member name="T:NetSharp.Deprecated.TcpClient">
- <summary>
- Provides methods for TCP communication with a connected <see cref="T:NetSharp.Deprecated.TcpServer"/> instance.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.TcpClient.#ctor">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpClient.SendBytesAsync(System.Byte[],System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpClient.SendBytesWithResponseAsync(System.Byte[],System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpClient.SendComplexAsync``2(``0,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpClient.SendSimpleAsync``1(``0,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.TcpServer">
- <summary>
- Provides methods for TCP communication with connected <see cref="T:NetSharp.Deprecated.TcpClient"/> instances.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.TcpServer.HandleClientAsync(NetSharp.Deprecated.Server.ClientHandlerArgs,System.Threading.CancellationToken)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpServer.#ctor(System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpServer.#ctor">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.TcpServer.RunAsync(System.Net.EndPoint)">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.TcpSocketOptions">
- <summary>
- Allows for manipulation of TCP socket options.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.TcpSocketOptions.#ctor(System.Net.Sockets.Socket@)">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.TcpSocketOptions.HopLimit">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.TcpSocketOptions.IsRoutingEnabled">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.TcpSocketOptions.UseLoopback">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.UdpClient">
- <summary>
- Provides methods for UDP communication with a connected <see cref="T:NetSharp.Deprecated.UdpServer"/> instance.
- </summary>
- </member>
- <member name="M:NetSharp.Deprecated.UdpClient.#ctor">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpClient.SendBytesAsync(System.Byte[],System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpClient.SendBytesWithResponseAsync(System.Byte[],System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpClient.SendComplexAsync``2(``0,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpClient.SendSimpleAsync``1(``0,System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.UdpServer">
- <summary>
- Provides methods for UDP communication with connected <see cref="T:NetSharp.Deprecated.UdpClient"/> instances.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.UdpServer.clientChannelOptions">
- <summary>
- The options that should be applied to every channel created to handle a client.
- </summary>
- </member>
- <member name="F:NetSharp.Deprecated.UdpServer.activeClients">
+ <member name="M:NetSharp.Packets.NetworkPacket.#ctor(NetSharp.Packets.NetworkPacket.NetworkPacketHeader,System.ReadOnlyMemory{System.Byte},NetSharp.Packets.NetworkPacket.NetworkPacketFooter)">
<summary>
- Holds currently connected and active clients, as well as their current received packet queues.
+ Constructs a new instance of the <see cref="T:NetSharp.Packets.NetworkPacket"/> struct.
</summary>
+ <param name="packetHeader">The header for this packet.</param>
+ <param name="packetDataBuffer">The data that should be stored in the packet.</param>
+ <param name="packetFooter">The footer for this packet.</param>
+ <exception cref="T:System.ArgumentException">
+ Thrown when the given <paramref name="packetDataBuffer"/> exceeds <see cref="F:NetSharp.Packets.NetworkPacket.TotalSize"/> bytes in size.
+ </exception>
</member>
- <member name="M:NetSharp.Deprecated.UdpServer.HandleClientAsync(NetSharp.Deprecated.Server.ClientHandlerArgs,System.Threading.CancellationToken)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpServer.#ctor(System.TimeSpan)">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpServer.#ctor">
- <inheritdoc />
- </member>
- <member name="M:NetSharp.Deprecated.UdpServer.RunAsync(System.Net.EndPoint)">
- <inheritdoc />
- </member>
- <member name="T:NetSharp.Deprecated.UdpSocketOptions">
+ <member name="M:NetSharp.Sockets.SocketAsyncOperations.HandleIoCompleted(System.Object,System.Net.Sockets.SocketAsyncEventArgs)">
<summary>
- Allows for manipulation of UDP socket options.
+ Event handler for the <see cref="E:System.Net.Sockets.SocketAsyncEventArgs.Completed"/> event.
</summary>
- </member>
- <member name="M:NetSharp.Deprecated.UdpSocketOptions.#ctor(System.Net.Sockets.Socket@)">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.UdpSocketOptions.HopLimit">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.UdpSocketOptions.IsRoutingEnabled">
- <inheritdoc />
- </member>
- <member name="P:NetSharp.Deprecated.UdpSocketOptions.UseLoopback">
- <inheritdoc />
+ <param name="sender">The object on which the event is raised.</param>
+ <param name="args">The event arguments.</param>
</member>
<member name="T:NetSharp.Deprecated.BiDictionary`2">
<summary>
@@ -2326,35 +211,25 @@
<member name="M:NetSharp.Deprecated.Conversion.EndianAwareBitConverter.ToUInt64(System.Span{System.Byte},System.Boolean)">
<inheritdoc cref="M:System.BitConverter.ToUInt64(System.ReadOnlySpan{System.Byte})"/>
</member>
- <member name="M:NetSharp.Packets.NetworkPacket.#ctor(NetSharp.Packets.NetworkPacket.NetworkPacketHeader,System.ReadOnlyMemory{System.Byte},NetSharp.Packets.NetworkPacket.NetworkPacketFooter)">
- <summary>
- Constructs a new instance of the <see cref="T:NetSharp.Packets.NetworkPacket"/> struct.
- </summary>
- <param name="packetHeader">The header for this packet.</param>
- <param name="packetDataBuffer">The data that should be stored in the packet.</param>
- <param name="packetFooter">The footer for this packet.</param>
- <exception cref="T:System.ArgumentException">
- Thrown when the given <paramref name="packetDataBuffer"/> exceeds <see cref="F:NetSharp.Packets.NetworkPacket.TotalSize"/> bytes in size.
- </exception>
- </member>
- <member name="M:NetSharp.Sockets.SocketAsyncOperations.HandleIoCompleted(System.Object,System.Net.Sockets.SocketAsyncEventArgs)">
- <summary>
- Event handler for the <see cref="E:System.Net.Sockets.SocketAsyncEventArgs.Completed"/> event.
- </summary>
- <param name="sender">The object on which the event is raised.</param>
- <param name="args">The event arguments.</param>
- </member>
<member name="T:NetSharp.Utils.TransmissionResult">
<summary>
Represents the result of a socket transmission.
</summary>
</member>
- <member name="M:NetSharp.Utils.TransmissionResult.#ctor(System.Net.Sockets.SocketAsyncEventArgs)">
+ <member name="M:NetSharp.Utils.TransmissionResult.#ctor(System.Net.Sockets.SocketAsyncEventArgs@)">
<summary>
Initialises a new instance of the <see cref="T:NetSharp.Utils.TransmissionResult"/> struct.
</summary>
<param name="args">The socket arguments associated with the transmission.</param>
</member>
+ <member name="M:NetSharp.Utils.TransmissionResult.#ctor(System.Byte[]@,System.Int32@,System.Net.EndPoint@)">
+ <summary>
+ Initialises a new instance of the <see cref="T:NetSharp.Utils.TransmissionResult"/> struct.
+ </summary>
+ <param name="buffer">The buffer associated with the transmission.</param>
+ <param name="count">The number of bytes written to or read from the buffer.</param>
+ <param name="remoteEndPoint">The remote end point associated with the transmission.</param>
+ </member>
<member name="F:NetSharp.Utils.TransmissionResult.Buffer">
<summary>
The byte buffer that was transmitted across the network.
@@ -2370,10 +245,5 @@
The remote endpoint to which the buffer was transmitted.
</summary>
</member>
- <member name="F:NetSharp.Utils.TransmissionResult.TransmissionArgs">
- <summary>
- Socket arguments and other data associated with the transmission.
- </summary>
- </member>
</members>
</doc>
diff --git a/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs b/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs
@@ -1,12 +1,173 @@
-using System.Net.Sockets;
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+using NetSharp.Utils;
namespace NetSharp.Sockets.Datagram
{
- public class DatagramSocketClient : SocketClient
+ //TODO document class
+ public sealed class DatagramSocketClient : SocketClient
{
+ private readonly struct SocketOperationToken
+ {
+ public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
+
+ public readonly CancellationToken CancellationToken;
+
+ public SocketOperationToken(in TaskCompletionSource<TransmissionResult> completionSource, in CancellationToken cancellationToken)
+ {
+ CompletionSource = completionSource;
+
+ CancellationToken = cancellationToken;
+ }
+ }
+
public DatagramSocketClient(in AddressFamily connectionAddressFamily, in ProtocolType connectionProtocolType)
: base(in connectionAddressFamily, SocketType.Dgram, in connectionProtocolType)
{
}
+
+ protected override SocketAsyncEventArgs CreateTransmissionArgs()
+ {
+ SocketAsyncEventArgs connectionArgs = new SocketAsyncEventArgs();
+
+ connectionArgs.Completed += HandleIoCompleted;
+
+ return connectionArgs;
+ }
+
+ protected override void ResetTransmissionArgs(SocketAsyncEventArgs args)
+ {
+ }
+
+ protected override bool CanTransmissionArgsBeReused(in SocketAsyncEventArgs args)
+ {
+ return true;
+ }
+
+ protected override void DestroyTransmissionArgs(SocketAsyncEventArgs remoteConnectionArgs)
+ {
+ remoteConnectionArgs.Completed -= HandleIoCompleted;
+
+ remoteConnectionArgs.Dispose();
+ }
+
+ protected override void HandleIoCompleted(object sender, SocketAsyncEventArgs args)
+ {
+ switch (args.LastOperation)
+ {
+ case SocketAsyncOperation.SendTo:
+ SocketOperationToken sendToken = (SocketOperationToken) args.UserToken;
+
+ if (sendToken.CancellationToken.IsCancellationRequested)
+ {
+ sendToken.CompletionSource.SetCanceled();
+ }
+ else if (args.SocketError == SocketError.Success)
+ {
+ TransmissionResult result = new TransmissionResult(in args);
+
+ sendToken.CompletionSource.SetResult(result);
+
+ TransmissionArgsPool.Return(args);
+ }
+ else
+ {
+ sendToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+
+ TransmissionArgsPool.Return(args);
+ }
+
+ break;
+
+ case SocketAsyncOperation.ReceiveFrom:
+ SocketOperationToken receiveToken = (SocketOperationToken)args.UserToken;
+
+ if (sendToken.CancellationToken.IsCancellationRequested)
+ {
+ receiveToken.CompletionSource.SetCanceled();
+ }
+ else if (args.SocketError == SocketError.Success)
+ {
+ TransmissionResult result = new TransmissionResult(in args);
+
+ receiveToken.CompletionSource.SetResult(result);
+
+ TransmissionArgsPool.Return(args);
+ }
+ else
+ {
+ receiveToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+
+ TransmissionArgsPool.Return(args);
+ }
+
+ break;
+
+ default:
+ throw new NotSupportedException($"{nameof(HandleIoCompleted)} doesn't support {args.LastOperation}");
+ }
+ }
+
+ public TransmissionResult SendTo(EndPoint remoteEndPoint, byte[] sendBuffer, SocketFlags flags = SocketFlags.None)
+ {
+ int sentBytes = connection.SendTo(sendBuffer, flags, remoteEndPoint);
+
+ return new TransmissionResult(in sendBuffer, in sentBytes, in remoteEndPoint);
+ }
+
+ public ValueTask<TransmissionResult> SendToAsync(EndPoint remoteEndPoint, Memory<byte> sendBuffer,
+ SocketFlags flags = SocketFlags.None, CancellationToken cancellationToken = default)
+ {
+ TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
+
+ SocketAsyncEventArgs args = TransmissionArgsPool.Rent();
+
+ args.SetBuffer(sendBuffer);
+
+ args.RemoteEndPoint = remoteEndPoint;
+ args.SocketFlags = flags;
+ args.UserToken = new SocketOperationToken(in tcs, in cancellationToken);
+
+ if (connection.SendToAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task);
+
+ TransmissionResult result = new TransmissionResult(in args);
+
+ TransmissionArgsPool.Return(args);
+
+ return new ValueTask<TransmissionResult>(result);
+
+ }
+
+ public TransmissionResult ReceiveFrom(ref EndPoint remoteEndPoint, byte[] receiveBuffer, SocketFlags flags = SocketFlags.None)
+ {
+ int readBytes = connection.ReceiveFrom(receiveBuffer, flags, ref remoteEndPoint);
+
+ return new TransmissionResult(in receiveBuffer, in readBytes, in remoteEndPoint);
+ }
+
+ public ValueTask<TransmissionResult> ReceiveFromAsync(EndPoint remoteEndPoint, Memory<byte> receiveBuffer,
+ SocketFlags flags = SocketFlags.None, CancellationToken cancellationToken = default)
+ {
+ TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
+
+ SocketAsyncEventArgs args = TransmissionArgsPool.Rent();
+
+ args.SetBuffer(receiveBuffer);
+
+ args.RemoteEndPoint = remoteEndPoint;
+ args.SocketFlags = flags;
+ args.UserToken = new SocketOperationToken(in tcs, in cancellationToken);
+
+ if (connection.ReceiveFromAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task);
+
+ TransmissionResult result = new TransmissionResult(in args);
+
+ TransmissionArgsPool.Return(args);
+
+ return new ValueTask<TransmissionResult>(result);
+ }
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketServer.cs b/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketServer.cs
@@ -1,226 +1,86 @@
using NetSharp.Utils;
using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
-using System.Threading.Channels;
using System.Threading.Tasks;
-using Microsoft.Extensions.ObjectPool;
-using NetSharp.Deprecated;
+
using NetworkPacket = NetSharp.Packets.NetworkPacket;
namespace NetSharp.Sockets.Datagram
{
- public class DatagramSocketServer : SocketServer
+ //TODO document
+ public readonly struct DatagramSocketServerOptions
{
- private static readonly EndPoint AnyRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ public static readonly DatagramSocketServerOptions Defaults =
+ new DatagramSocketServerOptions(NetworkPacket.TotalSize, 8);
- private readonly ConcurrentDictionary<EndPoint, RemoteDatagramClientToken> connectedClientTokens;
+ public readonly int PacketSize;
- private readonly MyObjectPool<SocketAsyncEventArgs> ArgsPool;
+ public readonly int ConcurrentReceiveFromCalls;
- private readonly struct RemoteDatagramClientToken
+ public DatagramSocketServerOptions(int packetSize, int concurrentReceiveFromCalls)
{
- private readonly Channel<NetworkPacket> PacketChannel;
-
- public readonly ChannelReader<NetworkPacket> PacketReader;
-
- public readonly ChannelWriter<NetworkPacket> PacketWriter;
-
- public RemoteDatagramClientToken(in Channel<NetworkPacket> packetChannel)
- {
- PacketChannel = packetChannel;
- PacketReader = packetChannel.Reader;
- PacketWriter = packetChannel.Writer;
- }
- }
-
- public DatagramSocketServer(in AddressFamily connectionAddressFamily, in ProtocolType connectionProtocolType)
- : base(in connectionAddressFamily, SocketType.Dgram, in connectionProtocolType)
- {
- connectedClientTokens = new ConcurrentDictionary<EndPoint, RemoteDatagramClientToken>();
-
- SocketAsyncEventArgs CreateArgs()
- {
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
-
- args.Completed += HandleIoCompleted;
-
- return args;
- }
-
- static void ResetArgs(SocketAsyncEventArgs args)
- {
-
- }
-
- void DestroyArgs(SocketAsyncEventArgs args)
- {
- args.Completed -= HandleIoCompleted;
-
- args.Dispose();
- }
-
- static bool ReBufferArgsPredicate(in SocketAsyncEventArgs args)
- {
- return true;
- }
+ PacketSize = packetSize;
- ArgsPool = new MyObjectPool<SocketAsyncEventArgs>(CreateArgs, ResetArgs, DestroyArgs, ReBufferArgsPredicate);
+ ConcurrentReceiveFromCalls = concurrentReceiveFromCalls;
}
+ }
- protected override SocketAsyncEventArgs GenerateConnectionArgs(EndPoint remoteEndPoint)
- {
- SocketAsyncEventArgs connectionArgs = new SocketAsyncEventArgs { RemoteEndPoint = remoteEndPoint };
+ //TODO address the need for a fixed packet size (NetworkPacket.TotalSize; lines 109 and 145)
+ //TODO address the need for a fixed number of initial ReceiveFrom method calls
+ //TODO address the need to handle series of network packets, not just single packets
+ public sealed class DatagramSocketServer : SocketServer
+ {
+ private static readonly EndPoint AnyRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
- connectionArgs.Completed += SocketAsyncOperations.HandleIoCompleted;
+ public readonly DatagramSocketServerOptions ServerOptions;
- return connectionArgs;
- }
-
- protected override void DestroyConnectionArgs(SocketAsyncEventArgs remoteConnectionArgs)
+ public DatagramSocketServer(in AddressFamily connectionAddressFamily, in ProtocolType connectionProtocolType,
+ in DatagramSocketServerOptions serverOptions = default) : base(in connectionAddressFamily, SocketType.Dgram,
+ in connectionProtocolType)
{
- remoteConnectionArgs.Completed -= SocketAsyncOperations.HandleIoCompleted;
-
- remoteConnectionArgs.Dispose();
+ ServerOptions = serverOptions.Equals(default) ? DatagramSocketServerOptions.Defaults : serverOptions;
}
- protected override async Task HandleClient(SocketAsyncEventArgs clientArgs, CancellationToken cancellationToken = default)
+ private readonly struct SocketOperationToken
{
- EndPoint clientEndPoint = clientArgs.RemoteEndPoint;
- RemoteDatagramClientToken clientToken = connectedClientTokens[clientEndPoint];
-
- byte[] responseBuffer = new byte[NetworkPacket.TotalSize];
- Memory<byte> responseBufferMemory = new Memory<byte>(responseBuffer);
+ public readonly byte[] RentedBuffer;
- try
+ public SocketOperationToken(in byte[] rentedBuffer)
{
- while (!cancellationToken.IsCancellationRequested)
- {
- NetworkPacket request = await clientToken.PacketReader.ReadAsync(cancellationToken);
-
- // TODO implement actual request handling, besides just an echo
- NetworkPacket response = request;
-
- NetworkPacket.Serialise(response, responseBufferMemory);
-
- TransmissionResult sendResult =
- await SocketAsyncOperations
- .SendToAsync(clientArgs, connection, clientEndPoint, SocketFlags.None, responseBufferMemory,
- cancellationToken);
-
-#if DEBUG
- lock (typeof(Console))
- {
- Console.WriteLine($"[Server] Sent {sendResult.Count} bytes to {sendResult.RemoteEndPoint}");
- Console.WriteLine($"[Server] >>>> {Encoding.UTF8.GetString(sendResult.Buffer.Span)}");
- }
-#endif
- }
- }
- catch (OperationCanceledException)
- {
- Console.WriteLine($"Client task for {clientArgs.RemoteEndPoint} cancelled!");
- }
- finally
- {
- DestroyConnectionArgs(clientArgs);
+ RentedBuffer = rentedBuffer;
}
}
- private readonly struct ClientRequest
+ protected override SocketAsyncEventArgs CreateTransmissionArgs()
{
- public readonly NetworkPacket RequestPacket;
-
- public readonly EndPoint ClientEndPoint;
+ SocketAsyncEventArgs connectionArgs = new SocketAsyncEventArgs();
- public readonly CancellationToken CancellationToken;
+ connectionArgs.Completed += HandleIoCompleted;
- public ClientRequest(in NetworkPacket requestPacket, in EndPoint clientEndPoint, in CancellationToken cancellationToken)
- {
- RequestPacket = requestPacket;
-
- ClientEndPoint = clientEndPoint;
-
- CancellationToken = cancellationToken;
- }
+ return connectionArgs;
}
- private async Task HandleClientRequest(ClientRequest clientRequest)
+ protected override void ResetTransmissionArgs(SocketAsyncEventArgs args)
{
- SocketAsyncEventArgs clientArgs = TransmissionArgsPool.Get();
-
- byte[] responseBuffer = BufferPool.Rent(NetworkPacket.TotalSize);
- Memory<byte> responseBufferMemory = new Memory<byte>(responseBuffer);
-
- NetworkPacket request = clientRequest.RequestPacket;
- EndPoint remoteEndPoint = clientRequest.ClientEndPoint;
- CancellationToken cancellationToken = clientRequest.CancellationToken;
-
- // TODO implement actual request handling, besides just an echo
- NetworkPacket response = request;
-
- NetworkPacket.Serialise(response, responseBufferMemory);
-
- TransmissionResult sendResult =
- await SocketAsyncOperations
- .SendToAsync(clientArgs, connection, remoteEndPoint, SocketFlags.None, responseBufferMemory, cancellationToken)
- .ConfigureAwait(false);
-
-#if DEBUG
- lock (typeof(Console))
- {
- Console.WriteLine($"[Server] Sent {sendResult.Count} bytes to {sendResult.RemoteEndPoint}");
- Console.WriteLine($"[Server] >>>> {Encoding.UTF8.GetString(sendResult.Buffer.Span)}");
- }
-#endif
-
- BufferPool.Return(responseBuffer, true);
-
- TransmissionArgsPool.Return(clientArgs);
}
- private readonly struct ClientPacket
+ protected override bool CanTransmissionArgsBeReused(in SocketAsyncEventArgs args)
{
- public readonly SocketAsyncEventArgs RentedArgs;
-
- public readonly byte[] RentedBuffer;
-
- public readonly Memory<byte> RentedBufferMemory;
-
- public readonly EndPoint RemoteEndPoint;
-
- public ClientPacket(in SocketAsyncEventArgs rentedArgs, in byte[] rentedBuffer, in Memory<byte> rentedBufferMemory, in EndPoint remoteEndPoint)
- {
- RentedArgs = rentedArgs;
-
- RentedBuffer = rentedBuffer;
-
- RentedBufferMemory = rentedBufferMemory;
-
- RemoteEndPoint = remoteEndPoint;
- }
+ return true;
}
- private readonly struct SocketOperationToken
+ protected override void DestroyTransmissionArgs(SocketAsyncEventArgs remoteConnectionArgs)
{
- public readonly byte[] RentedBuffer;
-
- public readonly Memory<byte> RentedBufferMemory;
-
- public SocketOperationToken(in byte[] rentedBuffer, in Memory<byte> rentedBufferMemory)
- {
- RentedBuffer = rentedBuffer;
+ remoteConnectionArgs.Completed -= HandleIoCompleted;
- RentedBufferMemory = rentedBufferMemory;
- }
+ remoteConnectionArgs.Dispose();
}
- private void HandleIoCompleted(object sender, SocketAsyncEventArgs args)
+ protected override void HandleIoCompleted(object sender, SocketAsyncEventArgs args)
{
switch (args.LastOperation)
{
@@ -229,7 +89,7 @@ namespace NetSharp.Sockets.Datagram
break;
case SocketAsyncOperation.ReceiveFrom:
- DoReceiveFrom(AnyRemoteEndPoint); // start a new receive from operation immediately, to not drop any packets
+ ReceiveFrom(AnyRemoteEndPoint); // start a new receive from operation immediately, to not drop any packets
CompleteReceiveFrom(args);
break;
@@ -239,11 +99,9 @@ namespace NetSharp.Sockets.Datagram
}
}
- private void DoSendTo(SocketAsyncEventArgs sendArgs)
+ private void SendTo(SocketAsyncEventArgs sendArgs)
{
- bool completesAsync = connection.SendToAsync(sendArgs);
-
- if (!completesAsync)
+ if (!connection.SendToAsync(sendArgs))
{
CompleteSendTo(sendArgs);
}
@@ -253,7 +111,7 @@ namespace NetSharp.Sockets.Datagram
{
SocketOperationToken sendToken = (SocketOperationToken) sendArgs.UserToken;
- TransmissionResult sendResult = new TransmissionResult(sendArgs);
+ TransmissionResult sendResult = new TransmissionResult(in sendArgs);
#if DEBUG
lock (typeof(Console))
@@ -265,25 +123,23 @@ namespace NetSharp.Sockets.Datagram
BufferPool.Return(sendToken.RentedBuffer, true);
- ArgsPool.Return(sendArgs);
+ TransmissionArgsPool.Return(sendArgs);
}
- private void DoReceiveFrom(EndPoint remoteEndPoint)
+ private void ReceiveFrom(EndPoint remoteEndPoint)
{
- SocketAsyncEventArgs args = ArgsPool.Rent();
+ SocketAsyncEventArgs args = TransmissionArgsPool.Rent();
byte[] receiveBuffer = BufferPool.Rent(NetworkPacket.TotalSize);
Memory<byte> receiveBufferMemory = new Memory<byte>(receiveBuffer);
args.SetBuffer(receiveBufferMemory);
args.RemoteEndPoint = remoteEndPoint;
- args.UserToken = new SocketOperationToken(in receiveBuffer, in receiveBufferMemory);
-
- bool completesAsync = connection.ReceiveFromAsync(args);
+ args.UserToken = new SocketOperationToken(in receiveBuffer);
- if (!completesAsync)
+ if (!connection.ReceiveFromAsync(args))
{
- DoReceiveFrom(AnyRemoteEndPoint); // start a new receive from operation immediately, to not drop any packets
+ ReceiveFrom(AnyRemoteEndPoint); // start a new receive from operation immediately, to not drop any packets
CompleteReceiveFrom(args);
}
@@ -293,7 +149,7 @@ namespace NetSharp.Sockets.Datagram
{
SocketOperationToken receiveToken = (SocketOperationToken)receiveArgs.UserToken;
- TransmissionResult receiveResult = new TransmissionResult(receiveArgs);
+ TransmissionResult receiveResult = new TransmissionResult(in receiveArgs);
#if DEBUG
lock (typeof(Console))
@@ -305,9 +161,10 @@ namespace NetSharp.Sockets.Datagram
NetworkPacket request = NetworkPacket.Deserialise(receiveArgs.MemoryBuffer);
+ // TODO implement actual request processing, not just an echo server
NetworkPacket response = request;
- SocketAsyncEventArgs sendArgs = ArgsPool.Rent();
+ SocketAsyncEventArgs sendArgs = TransmissionArgsPool.Rent();
byte[] sendBuffer = BufferPool.Rent(NetworkPacket.TotalSize);
Memory<byte> sendBufferMemory = new Memory<byte>(sendBuffer);
@@ -316,225 +173,23 @@ namespace NetSharp.Sockets.Datagram
sendArgs.SetBuffer(sendBufferMemory);
sendArgs.RemoteEndPoint = receiveResult.RemoteEndPoint;
- sendArgs.UserToken = new SocketOperationToken(in sendBuffer, in sendBufferMemory);
+ sendArgs.UserToken = new SocketOperationToken(in sendBuffer);
- DoSendTo(sendArgs);
+ SendTo(sendArgs);
BufferPool.Return(receiveToken.RentedBuffer, true);
- ArgsPool.Return(receiveArgs);
+ TransmissionArgsPool.Return(receiveArgs);
}
public override Task RunAsync(CancellationToken cancellationToken = default)
{
for (int i = 0; i < 10; i++)
{
- DoReceiveFrom(AnyRemoteEndPoint);
+ ReceiveFrom(AnyRemoteEndPoint);
}
return cancellationToken.WaitHandle.WaitOneAsync();
- /*
- UnboundedChannelOptions requestChannelOptions = new UnboundedChannelOptions()
- {
- AllowSynchronousContinuations = true,
- SingleReader = true,
- SingleWriter = true,
- };
- Channel<ClientPacket> requestChannel = Channel.CreateUnbounded<ClientPacket>(requestChannelOptions);
-
- UnboundedChannelOptions responseChannelOptions = new UnboundedChannelOptions()
- {
- AllowSynchronousContinuations = true,
- SingleReader = true,
- SingleWriter = true,
- };
- Channel<ClientPacket> responseChannel = Channel.CreateUnbounded<ClientPacket>(responseChannelOptions);
-
- async Task ReceivePacketTask()
- {
- EndPoint anyRemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
-
- while (!cancellationToken.IsCancellationRequested)
- {
- SocketAsyncEventArgs transmissionArgs = TransmissionArgsPool.Get();
-
- byte[] requestBuffer = BufferPool.Rent(NetworkPacket.TotalSize);
- Memory<byte> requestBufferMemory = new Memory<byte>(requestBuffer);
-
- TransmissionResult receiveResult =
- await SocketAsyncOperations
- .ReceiveFromAsync(transmissionArgs, connection, anyRemoteEndPoint, SocketFlags.None, requestBufferMemory, cancellationToken)
- .ConfigureAwait(false);
-
-#if DEBUG
- lock (typeof(Console))
- {
- Console.WriteLine($"[Server] Received {receiveResult.Count} bytes from {receiveResult.RemoteEndPoint}");
- Console.WriteLine($"[Server] <<<< {Encoding.UTF8.GetString(receiveResult.Buffer.Span)}");
- }
-#endif
- ClientPacket request = new ClientPacket(in transmissionArgs, in requestBuffer, in requestBufferMemory, in receiveResult.RemoteEndPoint);
-
- await requestChannel.Writer.WriteAsync(request, cancellationToken);
- }
- }
-
- async Task HandleRequestTask()
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- ClientPacket request = await requestChannel.Reader.ReadAsync(cancellationToken);
-
- NetworkPacket requestPacket = NetworkPacket.Deserialise(request.RentedBufferMemory);
-
- // TODO implement actual request handling, besides just an echo
- NetworkPacket responsePacket = requestPacket;
-
- byte[] responseBuffer = BufferPool.Rent(NetworkPacket.TotalSize);
- Memory<byte> responseBufferMemory = new Memory<byte>(responseBuffer);
-
- NetworkPacket.Serialise(responsePacket, responseBufferMemory);
-
- // after the response has been serialised to the response buffer, the request buffer is done with and can be freed
- BufferPool.Return(request.RentedBuffer, true);
-
- ClientPacket response = new ClientPacket(in request.RentedArgs, in responseBuffer, in responseBufferMemory, in request.RemoteEndPoint);
-
- await responseChannel.Writer.WriteAsync(response, cancellationToken);
- }
- }
-
- async Task SendResponseTask()
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- ClientPacket response = await responseChannel.Reader.ReadAsync(cancellationToken);
-
- EndPoint remoteEndPoint = response.RemoteEndPoint;
- Memory<byte> responseBufferMemory = response.RentedBufferMemory;
-
- TransmissionResult sendResult =
- await SocketAsyncOperations
- .SendToAsync(response.RentedArgs, connection, remoteEndPoint, SocketFlags.None, responseBufferMemory, cancellationToken)
- .ConfigureAwait(false);
-
-#if DEBUG
- lock (typeof(Console))
- {
- Console.WriteLine($"[Server] Sent {sendResult.Count} bytes to {sendResult.RemoteEndPoint}");
- Console.WriteLine($"[Server] >>>> {Encoding.UTF8.GetString(sendResult.Buffer.Span)}");
- }
-#endif
-
- BufferPool.Return(response.RentedBuffer, true);
-
- TransmissionArgsPool.Return(response.RentedArgs);
- }
- }
-
- // TODO this still functions as the simple example below, in fact it performs worse, with a worse bandwidth :(
- List<Task> completeTaskList = new List<Task>();
-
- Task[] readRequestTasks = new Task[2];
- for (int i = 0; i < readRequestTasks.Length; i++)
- {
- readRequestTasks[i] = ReceivePacketTask();
- completeTaskList.Add(readRequestTasks[i]);
- }
-
- Task[] handleRequestTasks = new Task[2];
- for (int i = 0; i < handleRequestTasks.Length; i++)
- {
- handleRequestTasks[i] = HandleRequestTask();
- completeTaskList.Add(handleRequestTasks[i]);
- }
-
- Task[] writeResponseTasks = new Task[2];
- for (int i = 0; i < writeResponseTasks.Length; i++)
- {
- writeResponseTasks[i] = SendResponseTask();
- completeTaskList.Add(writeResponseTasks[i]);
- }
-
- await Task.WhenAll(completeTaskList);
- */
-
- /*
- EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
- using SocketAsyncEventArgs remoteArgs = GenerateConnectionArgs(remoteEndPoint);
-
- byte[] requestBuffer = new byte[NetworkPacket.TotalSize];
- Memory<byte> requestBufferMemory = new Memory<byte>(requestBuffer);
-
- while (!cancellationToken.IsCancellationRequested)
- {
- TransmissionResult receiveResult =
- await SocketAsyncOperations
- .ReceiveFromAsync(remoteArgs, connection, remoteEndPoint, SocketFlags.None, requestBufferMemory, cancellationToken)
- .ConfigureAwait(false);
-
- EndPoint clientEndPoint = receiveResult.RemoteEndPoint;
-
-#if DEBUG
- lock (typeof(Console))
- {
- Console.WriteLine($"[Server] Received {receiveResult.Count} bytes from {receiveResult.RemoteEndPoint}");
- Console.WriteLine($"[Server] <<<< {Encoding.UTF8.GetString(receiveResult.Buffer.Span)}");
- }
-#endif
-
- NetworkPacket requestPacket = NetworkPacket.Deserialise(requestBufferMemory);
-
- ClientRequest request = new ClientRequest(in requestPacket, in clientEndPoint, in cancellationToken);
-
- Task _ = HandleClientRequest(request);
- }
- */
-
- /*
- EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
- using SocketAsyncEventArgs remoteArgs = GenerateConnectionArgs(remoteEndPoint);
-
- byte[] requestBuffer = new byte[NetworkPacket.TotalSize];
- Memory<byte> requestBufferMemory = new Memory<byte>(requestBuffer);
-
- while (!cancellationToken.IsCancellationRequested)
- {
- remoteArgs.RemoteEndPoint = remoteEndPoint;
-
- TransmissionResult receiveResult =
- await SocketAsyncOperations
- .ReceiveFromAsync(remoteArgs, connection, remoteEndPoint, SocketFlags.None, requestBufferMemory, cancellationToken)
- .ConfigureAwait(false);
-
- EndPoint clientEndPoint = receiveResult.RemoteEndPoint;
-
-#if DEBUG
- lock (typeof(Console))
- {
- Console.WriteLine($"[Server] Received {receiveResult.Count} bytes from {receiveResult.RemoteEndPoint}");
- Console.WriteLine($"[Server] <<<< {Encoding.UTF8.GetString(receiveResult.Buffer.Span)}");
- }
-#endif
-
- if (!ConnectedClientHandlerTasks.ContainsKey(clientEndPoint))
- {
- SocketAsyncEventArgs clientArgs = GenerateConnectionArgs(receiveResult.RemoteEndPoint);
-
- BoundedChannelOptions clientChannelOptions = new BoundedChannelOptions(60)
- { FullMode = BoundedChannelFullMode.DropOldest, SingleReader = true, SingleWriter = true };
- Channel<NetworkPacket> clientChannel = Channel.CreateBounded<NetworkPacket>(clientChannelOptions);
-
- connectedClientTokens[clientEndPoint] = new RemoteDatagramClientToken(in clientChannel);
-
- ConnectedClientHandlerTasks[clientEndPoint] = HandleClient(clientArgs, cancellationToken);
- }
-
- NetworkPacket request = NetworkPacket.Deserialise(requestBufferMemory);
-
- await connectedClientTokens[clientEndPoint].PacketWriter.WriteAsync(request, cancellationToken);
- }
- */
}
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharp/Sockets/SocketAsyncOperations.cs b/NetSharp/NetSharp/Sockets/SocketAsyncOperations.cs
@@ -101,7 +101,7 @@ namespace NetSharp.Sockets
}
else if (args.BytesTransferred > 0)
{
- TransmissionResult result = new TransmissionResult(args);
+ TransmissionResult result = new TransmissionResult(in args);
asyncReceiveToken.CompletionSource.SetResult(result);
}
@@ -130,7 +130,7 @@ namespace NetSharp.Sockets
}
else
{
- TransmissionResult result = new TransmissionResult(args);
+ TransmissionResult result = new TransmissionResult(in args);
asyncReceiveFromToken.CompletionSource.SetResult(result);
}
@@ -154,7 +154,7 @@ namespace NetSharp.Sockets
}
else
{
- TransmissionResult result = new TransmissionResult(args);
+ TransmissionResult result = new TransmissionResult(in args);
asyncSendToken.CompletionSource.SetResult(result);
}
@@ -178,7 +178,7 @@ namespace NetSharp.Sockets
}
else
{
- TransmissionResult result = new TransmissionResult(args);
+ TransmissionResult result = new TransmissionResult(in args);
asyncSendToToken.CompletionSource.SetResult(result);
}
@@ -245,7 +245,7 @@ namespace NetSharp.Sockets
// if the receive operation doesn't complete synchronously, returns the awaitable task
if (socket.ReceiveAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
- TransmissionResult result = new TransmissionResult(socketArgs);
+ TransmissionResult result = new TransmissionResult(in socketArgs);
return new ValueTask<TransmissionResult>(result);
}
@@ -263,7 +263,7 @@ namespace NetSharp.Sockets
// if the receive operation doesn't complete synchronously, returns the awaitable task
if (socket.ReceiveFromAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
- TransmissionResult result = new TransmissionResult(socketArgs);
+ TransmissionResult result = new TransmissionResult(in socketArgs);
return new ValueTask<TransmissionResult>(result);
}
@@ -281,7 +281,7 @@ namespace NetSharp.Sockets
// if the send operation doesn't complete synchronously, return the awaitable task
if (socket.SendAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
- TransmissionResult result = new TransmissionResult(socketArgs);
+ TransmissionResult result = new TransmissionResult(in socketArgs);
return new ValueTask<TransmissionResult>(result);
}
@@ -299,7 +299,7 @@ namespace NetSharp.Sockets
// if the send operation doesn't complete synchronously, return the awaitable task
if (socket.SendToAsync(socketArgs)) return new ValueTask<TransmissionResult>(tcs.Task);
- TransmissionResult result = new TransmissionResult(socketArgs);
+ TransmissionResult result = new TransmissionResult(in socketArgs);
return new ValueTask<TransmissionResult>(result);
}
diff --git a/NetSharp/NetSharp/Sockets/SocketClient.cs b/NetSharp/NetSharp/Sockets/SocketClient.cs
@@ -11,15 +11,11 @@ namespace NetSharp.Sockets
{
public abstract class SocketClient : SocketConnection
{
- protected readonly ArrayPool<byte> BufferPool;
-
protected readonly SocketAsyncEventArgs Args;
protected SocketClient(in AddressFamily connectionAddressFamily, in SocketType connectionSocketType, in ProtocolType connectionProtocolType)
: base(in connectionAddressFamily, in connectionSocketType, in connectionProtocolType)
{
- BufferPool = ArrayPool<byte>.Create(NetworkPacket.TotalSize, 10);
-
Args = new SocketAsyncEventArgs();
Args.Completed += SocketAsyncOperations.HandleIoCompleted;
}
@@ -34,11 +30,6 @@ namespace NetSharp.Sockets
return sentBytes;
}
- public ValueTask<TransmissionResult> SendBytesTo(Memory<byte> outgoingDataBuffer, EndPoint remoteEndPoint, SocketFlags flags = SocketFlags.None)
- {
- return SocketAsyncOperations.SendToAsync(Args, connection, remoteEndPoint, flags, outgoingDataBuffer);
- }
-
public int ReceiveBytes(Memory<byte> incomingDataBuffer, SocketFlags flags = SocketFlags.None)
{
byte[] temporaryBuffer = BufferPool.Rent(NetworkPacket.TotalSize);
@@ -48,10 +39,5 @@ namespace NetSharp.Sockets
return receivedBytes;
}
-
- public ValueTask<TransmissionResult> ReceiveBytesFrom(Memory<byte> incomingDataBuffer, ref EndPoint remoteEndPoint, SocketFlags flags = SocketFlags.None)
- {
- return SocketAsyncOperations.ReceiveFromAsync(Args, connection, remoteEndPoint, flags, incomingDataBuffer);
- }
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharp/Sockets/SocketConnection.cs b/NetSharp/NetSharp/Sockets/SocketConnection.cs
@@ -1,6 +1,9 @@
using System;
+using System.Buffers;
using System.Net;
using System.Net.Sockets;
+using NetSharp.Packets;
+using NetSharp.Utils;
namespace NetSharp.Sockets
{
@@ -8,11 +11,29 @@ namespace NetSharp.Sockets
{
protected readonly Socket connection;
+ protected readonly ArrayPool<byte> BufferPool;
+
+ protected readonly SlimObjectPool<SocketAsyncEventArgs> TransmissionArgsPool;
+
protected SocketConnection(in AddressFamily connectionAddressFamily, in SocketType connectionSocketType, in ProtocolType connectionProtocolType)
{
connection = new Socket(connectionAddressFamily, connectionSocketType, connectionProtocolType);
+
+ BufferPool = ArrayPool<byte>.Create(NetworkPacket.TotalSize, 1000);
+
+ TransmissionArgsPool = new SlimObjectPool<SocketAsyncEventArgs>(CreateTransmissionArgs, ResetTransmissionArgs, DestroyTransmissionArgs, CanTransmissionArgsBeReused);
}
+ protected abstract SocketAsyncEventArgs CreateTransmissionArgs();
+
+ protected abstract void ResetTransmissionArgs(SocketAsyncEventArgs args);
+
+ protected abstract bool CanTransmissionArgsBeReused(in SocketAsyncEventArgs args);
+
+ protected abstract void DestroyTransmissionArgs(SocketAsyncEventArgs remoteConnectionArgs);
+
+ protected abstract void HandleIoCompleted(object sender, SocketAsyncEventArgs args);
+
public void Bind(in EndPoint localEndPoint)
{
connection.Bind(localEndPoint);
diff --git a/NetSharp/NetSharp/Sockets/SocketServer.cs b/NetSharp/NetSharp/Sockets/SocketServer.cs
@@ -1,12 +1,8 @@
-using NetSharp.Packets;
-
-using System.Buffers;
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
-using Microsoft.Extensions.ObjectPool;
namespace NetSharp.Sockets
{
@@ -14,44 +10,12 @@ namespace NetSharp.Sockets
{
protected readonly ConcurrentDictionary<EndPoint, Task> ConnectedClientHandlerTasks;
- protected readonly ArrayPool<byte> BufferPool;
-
- protected readonly ObjectPool<SocketAsyncEventArgs> TransmissionArgsPool;
-
protected SocketServer(in AddressFamily connectionAddressFamily, in SocketType connectionSocketType, in ProtocolType connectionProtocolType)
: base(in connectionAddressFamily, in connectionSocketType, in connectionProtocolType)
{
- BufferPool = ArrayPool<byte>.Create(NetworkPacket.TotalSize, 100);
-
- TransmissionArgsPool = new DefaultObjectPool<SocketAsyncEventArgs>(new PooledSocketAsyncEventArgsPolicy());
-
ConnectedClientHandlerTasks = new ConcurrentDictionary<EndPoint, Task>();
}
- protected abstract SocketAsyncEventArgs GenerateConnectionArgs(EndPoint remoteEndPoint);
-
- protected abstract void DestroyConnectionArgs(SocketAsyncEventArgs remoteConnectionArgs);
-
- protected abstract Task HandleClient(SocketAsyncEventArgs clientArgs,
- CancellationToken cancellationToken = default);
-
public abstract Task RunAsync(CancellationToken cancellationToken = default);
}
-
- public class PooledSocketAsyncEventArgsPolicy : IPooledObjectPolicy<SocketAsyncEventArgs>
- {
- public SocketAsyncEventArgs Create()
- {
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
-
- args.Completed += SocketAsyncOperations.HandleIoCompleted;
-
- return args;
- }
-
- public bool Return(SocketAsyncEventArgs obj)
- {
- return true;
- }
- }
}
\ No newline at end of file
diff --git a/NetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs b/NetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs
@@ -19,5 +19,30 @@ namespace NetSharp.Sockets.Stream
{
connection.Disconnect(true);
}
+
+ protected override SocketAsyncEventArgs CreateTransmissionArgs()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ protected override void ResetTransmissionArgs(SocketAsyncEventArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ protected override bool CanTransmissionArgsBeReused(in SocketAsyncEventArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ protected override void DestroyTransmissionArgs(SocketAsyncEventArgs remoteConnectionArgs)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ protected override void HandleIoCompleted(object sender, SocketAsyncEventArgs args)
+ {
+ throw new System.NotImplementedException();
+ }
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharp/Sockets/Stream/StreamSocketServer.cs b/NetSharp/NetSharp/Sockets/Stream/StreamSocketServer.cs
@@ -11,6 +11,23 @@ using NetSharp.Utils;
namespace NetSharp.Sockets.Stream
{
+ public readonly struct StreamSocketServerOptions
+ {
+ public static readonly StreamSocketServerOptions Defaults =
+ new StreamSocketServerOptions(NetworkPacket.TotalSize, 8);
+
+ public readonly int PacketSize;
+
+ public readonly int ConcurrentReceiveCalls;
+
+ public StreamSocketServerOptions(int packetSize, int concurrentReceiveCalls)
+ {
+ PacketSize = packetSize;
+
+ ConcurrentReceiveCalls = concurrentReceiveCalls;
+ }
+ }
+
public class StreamSocketServer : SocketServer
{
private readonly ConcurrentDictionary<EndPoint, RemoteStreamClientToken> connectedClientTokens;
@@ -31,22 +48,37 @@ namespace NetSharp.Sockets.Stream
}
}
- public StreamSocketServer(in AddressFamily connectionAddressFamily, in ProtocolType connectionProtocolType)
- : base(in connectionAddressFamily, SocketType.Stream, in connectionProtocolType)
+ public readonly StreamSocketServerOptions ServerOptions;
+
+ public StreamSocketServer(in AddressFamily connectionAddressFamily, in ProtocolType connectionProtocolType,
+ in StreamSocketServerOptions serverOptions = default) : base(in connectionAddressFamily, SocketType.Stream,
+ in connectionProtocolType)
{
connectedClientTokens = new ConcurrentDictionary<EndPoint, RemoteStreamClientToken>();
+
+ ServerOptions = serverOptions.Equals(default) ? StreamSocketServerOptions.Defaults : serverOptions;
}
- protected override SocketAsyncEventArgs GenerateConnectionArgs(EndPoint remoteEndPoint)
+ protected override SocketAsyncEventArgs CreateTransmissionArgs()
{
- SocketAsyncEventArgs connectionArgs = new SocketAsyncEventArgs { RemoteEndPoint = remoteEndPoint };
+ SocketAsyncEventArgs connectionArgs = new SocketAsyncEventArgs();
- connectionArgs.Completed += SocketAsyncOperations.HandleIoCompleted;
+ connectionArgs.Completed += HandleIoCompleted;
return connectionArgs;
}
- protected override void DestroyConnectionArgs(SocketAsyncEventArgs remoteConnectionArgs)
+ protected override void ResetTransmissionArgs(SocketAsyncEventArgs args)
+ {
+
+ }
+
+ protected override bool CanTransmissionArgsBeReused(in SocketAsyncEventArgs args)
+ {
+ return false;
+ }
+
+ protected override void DestroyTransmissionArgs(SocketAsyncEventArgs remoteConnectionArgs)
{
remoteConnectionArgs.AcceptSocket.Shutdown(SocketShutdown.Both);
remoteConnectionArgs.AcceptSocket.Close();
@@ -56,7 +88,12 @@ namespace NetSharp.Sockets.Stream
remoteConnectionArgs.Dispose();
}
- protected override async Task HandleClient(SocketAsyncEventArgs clientArgs, CancellationToken cancellationToken = default)
+ protected override void HandleIoCompleted(object sender, SocketAsyncEventArgs args)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected async Task HandleClient(SocketAsyncEventArgs clientArgs, CancellationToken cancellationToken = default)
{
EndPoint clientEndPoint = clientArgs.AcceptSocket.RemoteEndPoint;
RemoteStreamClientToken clientToken = connectedClientTokens[clientEndPoint];
@@ -119,7 +156,7 @@ namespace NetSharp.Sockets.Stream
}
finally
{
- DestroyConnectionArgs(clientArgs);
+ TransmissionArgsPool.Return(clientArgs);
}
}
@@ -131,7 +168,7 @@ namespace NetSharp.Sockets.Stream
while (!cancellationToken.IsCancellationRequested)
{
- SocketAsyncEventArgs clientArgs = GenerateConnectionArgs(remoteEndPoint);
+ SocketAsyncEventArgs clientArgs = TransmissionArgsPool.Rent();
await SocketAsyncOperations.AcceptAsync(clientArgs, connection, cancellationToken);
diff --git a/NetSharp/NetSharp/Utils/MyObjectPool.cs b/NetSharp/NetSharp/Utils/MyObjectPool.cs
@@ -1,54 +0,0 @@
-using System.Collections.Concurrent;
-
-namespace NetSharp.Utils
-{
- internal class MyObjectPool<T> where T : class
- {
- internal delegate T CreateObjectDelegate();
-
- internal delegate bool KeepObjectPredicate(in T instance);
-
- internal delegate void ResetObjectDelegate(T instance);
-
- internal delegate void DestroyObjectDelegate(T instance);
-
- private readonly CreateObjectDelegate createObjectDelegate;
- private readonly KeepObjectPredicate rebufferObjectPredicate;
- private readonly ResetObjectDelegate resetObjectDelegate;
- private readonly DestroyObjectDelegate destroyObjectDelegate;
-
- private readonly ConcurrentBag<T> objectBuffer;
-
- internal MyObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, in DestroyObjectDelegate destroyDelegate, in KeepObjectPredicate keepObjectPredicate)
- {
- createObjectDelegate = createDelegate;
-
- resetObjectDelegate = resetDelegate;
-
- destroyObjectDelegate = destroyDelegate;
-
- rebufferObjectPredicate = keepObjectPredicate;
-
- objectBuffer = new ConcurrentBag<T>();
- }
-
- internal T Rent()
- {
- return objectBuffer.TryTake(out T result) ? result : createObjectDelegate();
- }
-
- internal void Return(T instance)
- {
- if (rebufferObjectPredicate(instance))
- {
- resetObjectDelegate(instance);
-
- objectBuffer.Add(instance);
- }
- else
- {
- destroyObjectDelegate(instance);
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/NetSharp/NetSharp/Utils/SlimObjectPool.cs b/NetSharp/NetSharp/Utils/SlimObjectPool.cs
@@ -0,0 +1,54 @@
+using System.Collections.Concurrent;
+
+namespace NetSharp.Utils
+{
+ public class SlimObjectPool<T> where T : class
+ {
+ public delegate T CreateObjectDelegate();
+
+ public delegate bool CanRebufferObjectPredicate(in T instance);
+
+ public delegate void ResetObjectDelegate(T instance);
+
+ public delegate void DestroyObjectDelegate(T instance);
+
+ private readonly CreateObjectDelegate createObjectDelegate;
+ private readonly CanRebufferObjectPredicate canObjectBeRebufferedPredicate;
+ private readonly ResetObjectDelegate resetObjectDelegate;
+ private readonly DestroyObjectDelegate destroyObjectDelegate;
+
+ private readonly ConcurrentQueue<T> objectBuffer;
+
+ public SlimObjectPool(in CreateObjectDelegate createDelegate, in ResetObjectDelegate resetDelegate, in DestroyObjectDelegate destroyDelegate, in CanRebufferObjectPredicate rebufferPredicate)
+ {
+ createObjectDelegate = createDelegate;
+
+ resetObjectDelegate = resetDelegate;
+
+ destroyObjectDelegate = destroyDelegate;
+
+ canObjectBeRebufferedPredicate = rebufferPredicate;
+
+ objectBuffer = new ConcurrentQueue<T>();
+ }
+
+ public T Rent()
+ {
+ return objectBuffer.TryDequeue(out T result) ? result : createObjectDelegate();
+ }
+
+ public void Return(T instance)
+ {
+ if (canObjectBeRebufferedPredicate(instance))
+ {
+ resetObjectDelegate(instance);
+
+ objectBuffer.Enqueue(instance);
+ }
+ else
+ {
+ destroyObjectDelegate(instance);
+ }
+ }
+ }
+}
+\ No newline at end of file
diff --git a/NetSharp/NetSharp/Utils/TransmissionResult.cs b/NetSharp/NetSharp/Utils/TransmissionResult.cs
@@ -13,15 +13,27 @@ namespace NetSharp.Utils
/// Initialises a new instance of the <see cref="TransmissionResult"/> struct.
/// </summary>
/// <param name="args">The socket arguments associated with the transmission.</param>
- internal TransmissionResult(SocketAsyncEventArgs args)
+ internal TransmissionResult(in SocketAsyncEventArgs args)
{
- TransmissionArgs = args;
Buffer = args.MemoryBuffer;
Count = args.BytesTransferred;
RemoteEndPoint = args.RemoteEndPoint;
}
/// <summary>
+ /// Initialises a new instance of the <see cref="TransmissionResult"/> struct.
+ /// </summary>
+ /// <param name="buffer">The buffer associated with the transmission.</param>
+ /// <param name="count">The number of bytes written to or read from the buffer.</param>
+ /// <param name="remoteEndPoint">The remote end point associated with the transmission.</param>
+ internal TransmissionResult(in byte[] buffer, in int count, in EndPoint remoteEndPoint)
+ {
+ Buffer = buffer;
+ Count = count;
+ RemoteEndPoint = remoteEndPoint;
+ }
+
+ /// <summary>
/// The byte buffer that was transmitted across the network.
/// </summary>
public readonly Memory<byte> Buffer;
@@ -35,10 +47,5 @@ namespace NetSharp.Utils
/// The remote endpoint to which the buffer was transmitted.
/// </summary>
public readonly EndPoint RemoteEndPoint;
-
- /// <summary>
- /// Socket arguments and other data associated with the transmission.
- /// </summary>
- public readonly SocketAsyncEventArgs TransmissionArgs;
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharpExamples/Program.cs b/NetSharp/NetSharpExamples/Program.cs
@@ -44,8 +44,8 @@ namespace NetSharpExamples
private static async Task TestSocketClient()
{
- const int clientCount = 24;
- const long packetsToSend = 100_000;
+ const int clientCount = 10;
+ const long packetsToSend = 1_000_000;
Task[] clientTasks = new Task[clientCount];
double[] clientBandwidths = new double[clientCount];
@@ -82,6 +82,8 @@ namespace NetSharpExamples
client.Connect(in ServerEndPoint);
#endif
+ EndPoint remoteEndPoint = ServerEndPoint;
+
byte[] requestBuffer = new byte[NetworkPacket.TotalSize];
Memory<byte> requestBufferMemory = new Memory<byte>(requestBuffer);
@@ -96,14 +98,15 @@ namespace NetSharpExamples
for (int i = 0; i < packetsToSend; i++)
{
- Encoding.UTF8.GetBytes($"Hello World! (Packet {i})").CopyTo(requestBufferMemory);
+ Encoding.UTF8.GetBytes($"[Client {id}] Hello World! (Packet {i})").CopyTo(requestBufferMemory);
rttStopwatch.Start();
bandwidthStopwatch.Start();
+
#if TCP
int sendResult = client.SendBytes(requestBufferMemory);
#else
- TransmissionResult sendResult = await client.SendBytesTo(requestBufferMemory, ServerEndPoint);
+ TransmissionResult sendResult = client.SendTo(remoteEndPoint, requestBuffer);
#endif
bandwidthStopwatch.Stop();
@@ -117,15 +120,13 @@ namespace NetSharpExamples
}
#endif
- EndPoint serverEndPoint = ServerEndPoint;
-
rttStopwatch.Start();
bandwidthStopwatch.Start();
#if TCP
int receiveResult = client.ReceiveBytes(responseBufferMemory);
#else
- TransmissionResult receiveResult = await client.ReceiveBytesFrom(responseBufferMemory, ref serverEndPoint);
+ TransmissionResult receiveResult = client.ReceiveFrom(ref remoteEndPoint, responseBuffer);
#endif
bandwidthStopwatch.Stop();
@@ -200,7 +201,7 @@ namespace NetSharpExamples
for (int clientId = 0; clientId < clientCount; clientId++)
{
- clientTasks[clientId] = Task.Factory.StartNew(ClientTask, clientId, TaskCreationOptions.LongRunning).Result;
+ clientTasks[clientId] = Task.Factory.StartNew(ClientTask, clientId, TaskCreationOptions.LongRunning);
}
await Task.WhenAll(clientTasks);