This commit is contained in:
EonaCat 2023-03-24 14:05:23 +01:00
parent ff98074f5b
commit fb824136d9
3 changed files with 90 additions and 68 deletions

View File

@ -18,9 +18,9 @@
<PackageTags>EonaCat, Network, .NET Standard, EonaCatHelpers, Jeroen, Saey, Protocol, Quic, UDP, TCP, Web, Server</PackageTags>
<PackageReleaseNotes></PackageReleaseNotes>
<Description>EonaCat Networking library with Quic, TCP, UDP and a Webserver</Description>
<Version>1.0.3</Version>
<AssemblyVersion>1.0.0.3</AssemblyVersion>
<FileVersion>1.0.0.3</FileVersion>
<Version>1.0.5</Version>
<AssemblyVersion>1.0.0.5</AssemblyVersion>
<FileVersion>1.0.0.5</FileVersion>
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>

View File

@ -26,7 +26,7 @@ namespace EonaCat.Sockets
/// <summary>
/// Buffer size
/// </summary>
public static int BufferSize { get; set; } = 8 * 1024; // 8KB
public static int BufferSize { get; set; } = 1024 * 1024; // 1024KB
/// <summary>
/// Socket connection state.

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using EonaCat.Helpers.Controls;
@ -35,7 +36,7 @@ namespace EonaCat.Sockets
/// <summary>
/// Interval to check for disconnected clients
/// </summary>
public int DisconnectionCheckInterval { get; set; } = 100;
public int DisconnectionCheckInterval { get; set; } = 50;
/// <summary>
/// Determines if we need to reuse the socket address
@ -251,20 +252,18 @@ namespace EonaCat.Sockets
/// </summary>
public Socket CustomTcpSocket { get; set; }
static void SetConnectionReset(Socket socket)
private static void SetConnectionReset(Socket socket)
{
try
if (socket.ProtocolType != ProtocolType.Udp || !RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (socket.ProtocolType == ProtocolType.Udp && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Disable ICMP packet shutdown (forcibly closed)
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
socket.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null);
};
return;
}
catch { }
// Disable ICMP packet shutdown (forcibly closed)
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
socket.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null);
}
private void ConfigureSocketOptions()
@ -313,18 +312,13 @@ namespace EonaCat.Sockets
switch (ServerType)
{
case NetworkType.Tcp:
Server.BeginAccept(AcceptCallback, Server);
BeginTcpAccept();
break;
case NetworkType.Udp:
var loopbackAddress = Server.AddressFamily == AddressFamily.InterNetworkV6
? IPAddress.IPv6Loopback
: IPAddress.Loopback;
var buffer = new byte[Client.BufferSize];
EndPoint remoteIp = new IPEndPoint(loopbackAddress, 0);
Server.BeginReceiveFrom(buffer, 0, Client.BufferSize, 0, ref remoteIp, UseClientManager ? AcceptClientsCallbackUDP : ReadClientCallbackUdp, new object[] { buffer, remoteIp, Server });
BeginUdpReceive();
break;
default:
throw new NotSupportedException("Protocol type not supported");
}
@ -335,6 +329,61 @@ namespace EonaCat.Sockets
}
}
private void BeginTcpAccept()
{
Server.BeginAccept(AcceptCallback, Server);
}
private void BeginUdpReceive()
{
var loopbackAddress = Server.AddressFamily == AddressFamily.InterNetworkV6
? IPAddress.IPv6Loopback
: IPAddress.Loopback;
var buffer = new byte[Client.BufferSize];
EndPoint remoteIp = new IPEndPoint(loopbackAddress, 0);
Server.BeginReceiveFrom(buffer, 0, Client.BufferSize, 0, ref remoteIp, UseClientManager ? AcceptClientsCallbackUdp : ReadClientCallbackUdp, new object[] { buffer, remoteIp, Server });
}
private void ReadCallback(IAsyncResult ar)
{
try
{
var client = (Client)ar.AsyncState;
var bytesRead = client.Socket.EndReceive(ar);
if (bytesRead > 0)
{
var data = new byte[bytesRead];
Array.Copy(client.Buffer, 0, data, 0, bytesRead);
OnReceived?.Invoke(this, new SocketServerDataEventArgs() { Client = client, Data = data });
// read any remaining data
while (client.Socket.Available > 0)
{
bytesRead = client.Socket.Receive(client.Buffer, 0, Client.BufferSize, SocketFlags.None);
data = new byte[bytesRead];
Array.Copy(client.Buffer, 0, data, 0, bytesRead);
OnReceived?.Invoke(this, new SocketServerDataEventArgs() { Client = client, Data = data });
}
client.Socket.BeginReceive(client.Buffer, 0, Client.BufferSize, 0, ReadCallback, client); // recursive call
}
else
{
OnDisconnected?.Invoke(this, new SocketServerClientEventArgs() { Client = client });
lock (ConnectedClients)
{
ConnectedClients.Remove(client);
}
}
}
catch (SocketException se)
{
OnError?.Invoke(this, new ErrorEventArgs(se));
}
catch (ObjectDisposedException) { }
}
private void AcceptCallback(IAsyncResult ar)
{
try
@ -350,39 +399,27 @@ namespace EonaCat.Sockets
{
ConnectedClients.Add(client);
}
OnConnected?.Invoke(this, new SocketServerClientEventArgs() { Client = client });
client.Socket.BeginReceive(client.Buffer, 0, Client.BufferSize, 0, ReadCallback, client);
listener.BeginAccept(AcceptCallback, Server);
}
catch (SocketException se)
{
OnError?.Invoke(this, new ErrorEventArgs(se));
}
catch (ObjectDisposedException) { }
}
client.Socket.BeginReceive(client.Buffer, 0, Client.BufferSize, 0, ReadCallback, client); // recursive call
private void ReadCallback(IAsyncResult ar)
{
try
{
var client = (Client)ar.AsyncState;
var bytesRead = client.Socket.EndReceive(ar);
if (bytesRead > 0)
Thread.Sleep(DisconnectionCheckInterval);
if (listener.IsBound) // check if the listener is still bound
{
var data = new byte[bytesRead];
Array.Copy(client.Buffer, 0, data, 0, bytesRead);
OnReceived?.Invoke(this, new SocketServerDataEventArgs() { Client = client, Data = data });
listener.BeginAccept(AcceptCallback, Server); // recursive call
}
client.Socket.BeginReceive(client.Buffer, 0, Client.BufferSize, 0, ReadCallback, client);
}
catch (SocketException se)
{
OnError?.Invoke(this, new ErrorEventArgs(se));
}
catch (ObjectDisposedException) { }
catch (ObjectDisposedException)
{
}
}
private void AcceptClientsCallbackUDP(IAsyncResult ar)
private void AcceptClientsCallbackUdp(IAsyncResult ar)
{
try
{
@ -413,7 +450,7 @@ namespace EonaCat.Sockets
}
}
if (bytesRead > 1)
if (bytesRead > 0)
{
var data = new byte[bytesRead];
Array.Copy(buffer, 0, data, 0, bytesRead);
@ -434,7 +471,7 @@ namespace EonaCat.Sockets
}
}
Server.BeginReceiveFrom(buffer, 0, Client.BufferSize, 0, ref remoteIp, AcceptClientsCallbackUDP, new object[] { buffer, remoteIp, listener });
Server.BeginReceiveFrom(buffer, 0, Client.BufferSize, 0, ref remoteIp, AcceptClientsCallbackUdp, new object[] { buffer, remoteIp, listener });
}
catch (SocketException se)
{
@ -452,7 +489,7 @@ namespace EonaCat.Sockets
var remoteIp = objects[1] as EndPoint;
var listener = objects[2] as Socket;
var bytesRead = listener.EndReceiveFrom(ar, ref remoteIp);
if (bytesRead > 0)
while (bytesRead > 0)
{
var data = new byte[bytesRead];
Array.Copy(buffer, 0, data, 0, bytesRead);
@ -465,8 +502,11 @@ namespace EonaCat.Sockets
Socket = new Socket(remoteIp.AddressFamily, SocketType.Dgram, ProtocolType.Udp)
}
});
// read any remaining data
bytesRead = listener.ReceiveFrom(buffer, 0, Client.BufferSize, SocketFlags.None, ref remoteIp);
}
Server.BeginReceiveFrom(buffer, 0, Client.BufferSize, 0, ref remoteIp, ReadClientCallbackUdp, new object[] { buffer, remoteIp, Server });
listener.BeginReceiveFrom(buffer, 0, Client.BufferSize, 0, ref remoteIp, ReadClientCallbackUdp, new object[] { buffer, remoteIp, listener });
}
catch (SocketException se)
{
@ -475,24 +515,6 @@ namespace EonaCat.Sockets
catch (ObjectDisposedException) { }
}
private void DisconnectCallback(IAsyncResult ar)
{
try
{
var client = (Client)ar.AsyncState;
client.Socket.EndDisconnect(ar);
OnDisconnected?.Invoke(this, new SocketServerClientEventArgs() { Client = client });
lock (ConnectedClients)
{
ConnectedClients.Remove(client);
}
}
catch (SocketException se)
{
OnError?.Invoke(this, new ErrorEventArgs(se));
}
}
public void SendData(byte[] data, EndPoint point)
{
try