diff --git a/EonaCat.Network/EonaCat.Network.csproj b/EonaCat.Network/EonaCat.Network.csproj index 19589ce..7efc785 100644 --- a/EonaCat.Network/EonaCat.Network.csproj +++ b/EonaCat.Network/EonaCat.Network.csproj @@ -2,8 +2,7 @@ Latest - netstandard2.0; - netstandard2.1; + netstandard2.1; net5.0; net6.0; net7.0; @@ -18,9 +17,9 @@ EonaCat, Network, .NET Standard, EonaCatHelpers, Jeroen, Saey, Protocol, Quic, UDP, TCP, Web, Server EonaCat Networking library with Quic, TCP, UDP and a Webserver - 1.0.6 - 1.0.0.6 - 1.0.0.6 + 1.0.8 + 1.0.0.8 + 1.0.0.8 icon.png diff --git a/EonaCat.Network/System/Sockets/Tcp/SocketTcpClient.cs b/EonaCat.Network/System/Sockets/Tcp/SocketTcpClient.cs index d110bdb..f637c61 100644 --- a/EonaCat.Network/System/Sockets/Tcp/SocketTcpClient.cs +++ b/EonaCat.Network/System/Sockets/Tcp/SocketTcpClient.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; @@ -12,6 +11,7 @@ namespace EonaCat.Network public event Action OnReceive; public event Action OnDisconnect; public event Action OnSend; + public event Action OnError; private Socket socket; @@ -33,47 +33,48 @@ namespace EonaCat.Network { await socket.ConnectAsync(ipAddress, port).ConfigureAwait(false); OnConnect?.Invoke(new RemoteInfo { IsTcp = true, IsIpv6 = IsIP6 }); - _ = StartReceivingAsync(); + await StartReceivingAsync(); } catch (SocketException ex) { - Console.WriteLine($"SocketException: {ex.Message}"); + OnError?.Invoke(ex, $"SocketException: {ex.Message}"); Disconnect(); } } public bool IsIP6 { get; private set; } - private Task StartReceivingAsync() + private async Task StartReceivingAsync() { byte[] buffer = new byte[1024]; - return Task.Factory.StartNew(async () => + while (socket.Connected) { - while (socket.Connected) + try { - try + int received = await socket.ReceiveAsync(new ArraySegment(buffer), SocketFlags.None).ConfigureAwait(false); + if (received > 0) { - int received = await socket.ReceiveAsync(new ArraySegment(buffer), SocketFlags.None).ConfigureAwait(false); - if (received > 0) + byte[] data = buffer.AsSpan(0, received).ToArray(); + OnReceive?.Invoke(new RemoteInfo { - byte[] data = new byte[received]; - Array.Copy(buffer, data, received); - OnReceive?.Invoke(new RemoteInfo - { IsTcp = true, Data = data, EndPoint = socket.RemoteEndPoint, IsIpv6 = IsIP6 }); - } - else - { - break; - } + IsTcp = true, + Data = data, + EndPoint = socket.RemoteEndPoint, + IsIpv6 = IsIP6 + }); } - catch (SocketException ex) + else { - Console.WriteLine($"SocketException: {ex.Message}"); break; } } - OnDisconnect?.Invoke(new RemoteInfo { IsTcp = true, EndPoint = socket.RemoteEndPoint, IsIpv6 = IsIP6 }); - }); + catch (SocketException ex) + { + OnError?.Invoke(ex, $"SocketException: {ex.Message}"); + break; + } + } + OnDisconnect?.Invoke(new RemoteInfo { IsTcp = true, EndPoint = socket.RemoteEndPoint, IsIpv6 = IsIP6 }); } public async Task SendAsync(byte[] data) diff --git a/EonaCat.Network/System/Sockets/Tcp/SocketTcpServer.cs b/EonaCat.Network/System/Sockets/Tcp/SocketTcpServer.cs index 5a08f29..296cebf 100644 --- a/EonaCat.Network/System/Sockets/Tcp/SocketTcpServer.cs +++ b/EonaCat.Network/System/Sockets/Tcp/SocketTcpServer.cs @@ -2,6 +2,7 @@ using System.Net; using System; using System.Threading.Tasks; +using System.Threading; namespace EonaCat.Network { @@ -11,6 +12,7 @@ namespace EonaCat.Network public event Action OnReceive; public event Action OnSend; public event Action OnDisconnect; + public event Action OnError; private TcpListener listener; @@ -25,38 +27,49 @@ namespace EonaCat.Network listener = new TcpListener(address, port); } - public async Task Start() + public async Task StartAsync(CancellationToken cancellationToken = default) { listener.Start(); - while (true) + while (!cancellationToken.IsCancellationRequested) { try { - TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false); - Socket socket = client.Client; - OnConnect?.Invoke(new RemoteInfo { Socket = socket, IsTcp = true, IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, EndPoint = socket.RemoteEndPoint }); - _ = StartReceiving(socket); + Socket socket = await listener.AcceptSocketAsync().ConfigureAwait(false); + OnConnect?.Invoke(new RemoteInfo + { + Socket = socket, + IsTcp = true, + IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, + EndPoint = socket.RemoteEndPoint + }); + await StartReceivingAsync(socket, cancellationToken).ConfigureAwait(false); } catch (SocketException ex) { - Console.WriteLine($"SocketException: {ex.Message}"); + OnError?.Invoke(ex, $"SocketException: {ex.Message}"); } } } - private async Task StartReceiving(Socket socket) + private async Task StartReceivingAsync(Socket socket, CancellationToken cancellationToken) { byte[] buffer = new byte[1024]; - while (socket.Connected) + while (!cancellationToken.IsCancellationRequested) { try { - int received = await socket.ReceiveAsync(new ArraySegment(buffer), SocketFlags.None).ConfigureAwait(false); + int received = await socket.ReceiveAsync(new Memory(buffer), SocketFlags.None, cancellationToken) + .ConfigureAwait(false); if (received > 0) { - byte[] data = new byte[received]; - Array.Copy(buffer, data, received); - OnReceive?.Invoke(new RemoteInfo { Socket = socket, IsTcp = true, IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, EndPoint = socket.RemoteEndPoint, Data = data}); + OnReceive?.Invoke(new RemoteInfo + { + Socket = socket, + IsTcp = true, + IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, + EndPoint = socket.RemoteEndPoint, + Data = new Memory(buffer, 0, received).ToArray() + }); } else { @@ -65,11 +78,10 @@ namespace EonaCat.Network } catch (SocketException ex) { - Console.WriteLine($"SocketException: {ex.Message}"); + OnError?.Invoke(ex, $"SocketException: {ex.Message}"); break; } } - OnDisconnect?.Invoke(new RemoteInfo {Socket = socket, IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, IsTcp = true, EndPoint = socket.RemoteEndPoint }); } public async Task SendTo(Socket socket, byte[] data) diff --git a/EonaCat.Network/System/Sockets/Udp/SocketUdpClient.cs b/EonaCat.Network/System/Sockets/Udp/SocketUdpClient.cs index 7cd720d..ad40b1c 100644 --- a/EonaCat.Network/System/Sockets/Udp/SocketUdpClient.cs +++ b/EonaCat.Network/System/Sockets/Udp/SocketUdpClient.cs @@ -2,6 +2,7 @@ using System.Net; using System.Threading.Tasks; using System; +using System.Threading; namespace EonaCat.Network { @@ -11,15 +12,16 @@ namespace EonaCat.Network public event Action OnReceive; public event Action OnDisconnect; public event Action OnSend; + public event Action OnError; private UdpClient udpClient; - public SocketUdpClient(IPAddress ipAddress, int port) + public SocketUdpClient(IPAddress ipAddress, int port, CancellationToken cancellationToken = default) { - CreateUdpClient(ipAddress, port); + CreateUdpClient(ipAddress, port, cancellationToken); } - private void CreateUdpClient(IPAddress ipAddress, int port) + private void CreateUdpClient(IPAddress ipAddress, int port, CancellationToken cancellationToken = default) { IsIP6 = ipAddress.AddressFamily == AddressFamily.InterNetworkV6; udpClient = new UdpClient(ipAddress.AddressFamily); @@ -36,7 +38,7 @@ namespace EonaCat.Network udpClient.JoinMulticastGroup(ipAddress); } - _ = StartReceivingAsync(); + _ = StartReceivingAsync(cancellationToken); } public bool IsMulticastGroupEnabled { get; set; } @@ -53,25 +55,22 @@ namespace EonaCat.Network CreateUdpClient(ip, port); } - private Task StartReceivingAsync() + private async Task StartReceivingAsync(CancellationToken cancellationToken = default) { - return Task.Factory.StartNew(async () => + while (!cancellationToken.IsCancellationRequested) { - while (true) + try { - try - { - UdpReceiveResult result = await udpClient.ReceiveAsync(); - OnReceive?.Invoke(result.Buffer); - } - catch (SocketException ex) - { - Console.WriteLine($"SocketException: {ex.Message}"); - break; - } + UdpReceiveResult result = await udpClient.ReceiveAsync().ConfigureAwait(false); + OnReceive?.Invoke(result.Buffer); } - OnDisconnect?.Invoke(udpClient.Client.LocalEndPoint); - }); + catch (SocketException ex) + { + OnError?.Invoke(ex, $"SocketException: {ex.Message}"); + break; + } + } + OnDisconnect?.Invoke(udpClient.Client.RemoteEndPoint); } public async Task SendTo(EndPoint endPoint, byte[] data) diff --git a/EonaCat.Network/System/Sockets/Udp/SocketUdpServer.cs b/EonaCat.Network/System/Sockets/Udp/SocketUdpServer.cs index b2610a6..5f42a5a 100644 --- a/EonaCat.Network/System/Sockets/Udp/SocketUdpServer.cs +++ b/EonaCat.Network/System/Sockets/Udp/SocketUdpServer.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.InteropServices; using System.Net.NetworkInformation; using System.Threading.Tasks; +using System.Threading; namespace EonaCat.Network { @@ -11,6 +12,7 @@ namespace EonaCat.Network { public event Action OnReceive; public event Action OnSend; + public event Action OnError; public event Action OnDisconnect; @@ -62,28 +64,25 @@ namespace EonaCat.Network udpClient.Client.Bind(new IPEndPoint(ipAddress, port)); } - public Task StartAsync() + public async Task StartAsync(CancellationToken cancellationToken = default) { - return Task.Factory.StartNew(async () => + while (!cancellationToken.IsCancellationRequested) { - while (true) + try { - try + UdpReceiveResult result = await udpClient.ReceiveAsync().ConfigureAwait(false); + OnReceive?.Invoke(new RemoteInfo() { - UdpReceiveResult result = await udpClient.ReceiveAsync().ConfigureAwait(false); - OnReceive?.Invoke(new RemoteInfo() - { - EndPoint = result.RemoteEndPoint, - IsIpv6 = result.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, - Data = result.Buffer - }); - } - catch (SocketException ex) - { - Console.WriteLine($"SocketException: {ex.Message}"); - } + EndPoint = result.RemoteEndPoint, + IsIpv6 = result.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, + Data = result.Buffer + }); } - }); + catch (SocketException ex) + { + OnError?.Invoke(ex, $"SocketException: {ex.Message}"); + } + } } public async Task SendToAsync(EndPoint endPoint, byte[] data)