diff --git a/EonaCat.Network/EonaCat.Network.csproj b/EonaCat.Network/EonaCat.Network.csproj
index 9c7f28c..8a29e46 100644
--- a/EonaCat.Network/EonaCat.Network.csproj
+++ b/EonaCat.Network/EonaCat.Network.csproj
@@ -18,9 +18,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.3
- 1.0.0.3
- 1.0.0.3
+ 1.0.5
+ 1.0.0.5
+ 1.0.0.5
icon.png
diff --git a/EonaCat.Network/System/Sockets/Client.cs b/EonaCat.Network/System/Sockets/Client.cs
index dda9ab9..b45b8b3 100644
--- a/EonaCat.Network/System/Sockets/Client.cs
+++ b/EonaCat.Network/System/Sockets/Client.cs
@@ -26,7 +26,7 @@ namespace EonaCat.Sockets
///
/// Buffer size
///
- public static int BufferSize { get; set; } = 8 * 1024; // 8KB
+ public static int BufferSize { get; set; } = 1024 * 1024; // 1024KB
///
/// Socket connection state.
diff --git a/EonaCat.Network/System/Sockets/SocketServer.cs b/EonaCat.Network/System/Sockets/SocketServer.cs
index b5693d4..6077249 100644
--- a/EonaCat.Network/System/Sockets/SocketServer.cs
+++ b/EonaCat.Network/System/Sockets/SocketServer.cs
@@ -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
///
/// Interval to check for disconnected clients
///
- public int DisconnectionCheckInterval { get; set; } = 100;
+ public int DisconnectionCheckInterval { get; set; } = 50;
///
/// Determines if we need to reuse the socket address
@@ -251,20 +252,18 @@ namespace EonaCat.Sockets
///
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