This commit is contained in:
EonaCat 2023-03-27 15:09:24 +02:00
parent 2ca8cb31dc
commit 604d9cbc6b
5 changed files with 88 additions and 78 deletions

View File

@ -2,8 +2,7 @@
<PropertyGroup> <PropertyGroup>
<LangVersion>Latest</LangVersion> <LangVersion>Latest</LangVersion>
<TargetFrameworks> <TargetFrameworks>
netstandard2.0; netstandard2.1;
netstandard2.1;
net5.0; net5.0;
net6.0; net6.0;
net7.0; net7.0;
@ -18,9 +17,9 @@
<PackageTags>EonaCat, Network, .NET Standard, EonaCatHelpers, Jeroen, Saey, Protocol, Quic, UDP, TCP, Web, Server</PackageTags> <PackageTags>EonaCat, Network, .NET Standard, EonaCatHelpers, Jeroen, Saey, Protocol, Quic, UDP, TCP, Web, Server</PackageTags>
<PackageReleaseNotes></PackageReleaseNotes> <PackageReleaseNotes></PackageReleaseNotes>
<Description>EonaCat Networking library with Quic, TCP, UDP and a Webserver</Description> <Description>EonaCat Networking library with Quic, TCP, UDP and a Webserver</Description>
<Version>1.0.6</Version> <Version>1.0.8</Version>
<AssemblyVersion>1.0.0.6</AssemblyVersion> <AssemblyVersion>1.0.0.8</AssemblyVersion>
<FileVersion>1.0.0.6</FileVersion> <FileVersion>1.0.0.8</FileVersion>
<PackageIcon>icon.png</PackageIcon> <PackageIcon>icon.png</PackageIcon>
</PropertyGroup> </PropertyGroup>

View File

@ -1,5 +1,4 @@
using System; using System;
using System.ComponentModel;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -12,6 +11,7 @@ namespace EonaCat.Network
public event Action<RemoteInfo> OnReceive; public event Action<RemoteInfo> OnReceive;
public event Action<RemoteInfo> OnDisconnect; public event Action<RemoteInfo> OnDisconnect;
public event Action<RemoteInfo> OnSend; public event Action<RemoteInfo> OnSend;
public event Action<Exception, string> OnError;
private Socket socket; private Socket socket;
@ -33,47 +33,48 @@ namespace EonaCat.Network
{ {
await socket.ConnectAsync(ipAddress, port).ConfigureAwait(false); await socket.ConnectAsync(ipAddress, port).ConfigureAwait(false);
OnConnect?.Invoke(new RemoteInfo { IsTcp = true, IsIpv6 = IsIP6 }); OnConnect?.Invoke(new RemoteInfo { IsTcp = true, IsIpv6 = IsIP6 });
_ = StartReceivingAsync(); await StartReceivingAsync();
} }
catch (SocketException ex) catch (SocketException ex)
{ {
Console.WriteLine($"SocketException: {ex.Message}"); OnError?.Invoke(ex, $"SocketException: {ex.Message}");
Disconnect(); Disconnect();
} }
} }
public bool IsIP6 { get; private set; } public bool IsIP6 { get; private set; }
private Task StartReceivingAsync() private async Task StartReceivingAsync()
{ {
byte[] buffer = new byte[1024]; 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<byte>(buffer), SocketFlags.None).ConfigureAwait(false);
if (received > 0)
{ {
int received = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None).ConfigureAwait(false); byte[] data = buffer.AsSpan(0, received).ToArray();
if (received > 0) OnReceive?.Invoke(new RemoteInfo
{ {
byte[] data = new byte[received]; IsTcp = true,
Array.Copy(buffer, data, received); Data = data,
OnReceive?.Invoke(new RemoteInfo EndPoint = socket.RemoteEndPoint,
{ IsTcp = true, Data = data, EndPoint = socket.RemoteEndPoint, IsIpv6 = IsIP6 }); IsIpv6 = IsIP6
} });
else
{
break;
}
} }
catch (SocketException ex) else
{ {
Console.WriteLine($"SocketException: {ex.Message}");
break; 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) public async Task SendAsync(byte[] data)

View File

@ -2,6 +2,7 @@
using System.Net; using System.Net;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading;
namespace EonaCat.Network namespace EonaCat.Network
{ {
@ -11,6 +12,7 @@ namespace EonaCat.Network
public event Action<RemoteInfo> OnReceive; public event Action<RemoteInfo> OnReceive;
public event Action<RemoteInfo> OnSend; public event Action<RemoteInfo> OnSend;
public event Action<RemoteInfo> OnDisconnect; public event Action<RemoteInfo> OnDisconnect;
public event Action<Exception, string> OnError;
private TcpListener listener; private TcpListener listener;
@ -25,38 +27,49 @@ namespace EonaCat.Network
listener = new TcpListener(address, port); listener = new TcpListener(address, port);
} }
public async Task Start() public async Task StartAsync(CancellationToken cancellationToken = default)
{ {
listener.Start(); listener.Start();
while (true) while (!cancellationToken.IsCancellationRequested)
{ {
try try
{ {
TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false); Socket socket = await listener.AcceptSocketAsync().ConfigureAwait(false);
Socket socket = client.Client; OnConnect?.Invoke(new RemoteInfo
OnConnect?.Invoke(new RemoteInfo { Socket = socket, IsTcp = true, IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, EndPoint = socket.RemoteEndPoint }); {
_ = StartReceiving(socket); Socket = socket,
IsTcp = true,
IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6,
EndPoint = socket.RemoteEndPoint
});
await StartReceivingAsync(socket, cancellationToken).ConfigureAwait(false);
} }
catch (SocketException ex) 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]; byte[] buffer = new byte[1024];
while (socket.Connected) while (!cancellationToken.IsCancellationRequested)
{ {
try try
{ {
int received = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None).ConfigureAwait(false); int received = await socket.ReceiveAsync(new Memory<byte>(buffer), SocketFlags.None, cancellationToken)
.ConfigureAwait(false);
if (received > 0) if (received > 0)
{ {
byte[] data = new byte[received]; OnReceive?.Invoke(new RemoteInfo
Array.Copy(buffer, data, received); {
OnReceive?.Invoke(new RemoteInfo { Socket = socket, IsTcp = true, IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6, EndPoint = socket.RemoteEndPoint, Data = data}); Socket = socket,
IsTcp = true,
IsIpv6 = socket.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6,
EndPoint = socket.RemoteEndPoint,
Data = new Memory<byte>(buffer, 0, received).ToArray()
});
} }
else else
{ {
@ -65,11 +78,10 @@ namespace EonaCat.Network
} }
catch (SocketException ex) catch (SocketException ex)
{ {
Console.WriteLine($"SocketException: {ex.Message}"); OnError?.Invoke(ex, $"SocketException: {ex.Message}");
break; 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) public async Task SendTo(Socket socket, byte[] data)

View File

@ -2,6 +2,7 @@
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System; using System;
using System.Threading;
namespace EonaCat.Network namespace EonaCat.Network
{ {
@ -11,15 +12,16 @@ namespace EonaCat.Network
public event Action<byte[]> OnReceive; public event Action<byte[]> OnReceive;
public event Action<EndPoint> OnDisconnect; public event Action<EndPoint> OnDisconnect;
public event Action<EndPoint, byte[]> OnSend; public event Action<EndPoint, byte[]> OnSend;
public event Action<Exception, string> OnError;
private UdpClient udpClient; 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; IsIP6 = ipAddress.AddressFamily == AddressFamily.InterNetworkV6;
udpClient = new UdpClient(ipAddress.AddressFamily); udpClient = new UdpClient(ipAddress.AddressFamily);
@ -36,7 +38,7 @@ namespace EonaCat.Network
udpClient.JoinMulticastGroup(ipAddress); udpClient.JoinMulticastGroup(ipAddress);
} }
_ = StartReceivingAsync(); _ = StartReceivingAsync(cancellationToken);
} }
public bool IsMulticastGroupEnabled { get; set; } public bool IsMulticastGroupEnabled { get; set; }
@ -53,25 +55,22 @@ namespace EonaCat.Network
CreateUdpClient(ip, port); 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().ConfigureAwait(false);
{ OnReceive?.Invoke(result.Buffer);
UdpReceiveResult result = await udpClient.ReceiveAsync();
OnReceive?.Invoke(result.Buffer);
}
catch (SocketException ex)
{
Console.WriteLine($"SocketException: {ex.Message}");
break;
}
} }
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) public async Task SendTo(EndPoint endPoint, byte[] data)

View File

@ -4,6 +4,7 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading;
namespace EonaCat.Network namespace EonaCat.Network
{ {
@ -11,6 +12,7 @@ namespace EonaCat.Network
{ {
public event Action<RemoteInfo> OnReceive; public event Action<RemoteInfo> OnReceive;
public event Action<RemoteInfo> OnSend; public event Action<RemoteInfo> OnSend;
public event Action<Exception, string> OnError;
public event Action<RemoteInfo> OnDisconnect; public event Action<RemoteInfo> OnDisconnect;
@ -62,28 +64,25 @@ namespace EonaCat.Network
udpClient.Client.Bind(new IPEndPoint(ipAddress, port)); 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); EndPoint = result.RemoteEndPoint,
OnReceive?.Invoke(new RemoteInfo() IsIpv6 = result.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6,
{ Data = result.Buffer
EndPoint = result.RemoteEndPoint, });
IsIpv6 = result.RemoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6,
Data = result.Buffer
});
}
catch (SocketException ex)
{
Console.WriteLine($"SocketException: {ex.Message}");
}
} }
}); catch (SocketException ex)
{
OnError?.Invoke(ex, $"SocketException: {ex.Message}");
}
}
} }
public async Task SendToAsync(EndPoint endPoint, byte[] data) public async Task SendToAsync(EndPoint endPoint, byte[] data)