Updated
This commit is contained in:
parent
ff98074f5b
commit
fb824136d9
|
@ -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>
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue