using System.Net.Sockets; using System.Net; using System.Drawing; namespace DroneSimulator { internal class NetServerClients { public class ConnectData { public int ID; public bool Connect; public int Count; public Socket? Client; } public class ReceiveData { public int ID; public byte[] Buffer; public int Size; public Socket? Client; } private class ClientData { public int ID; public Socket? workSocket = null; public const int count = 1024; public byte[] buffer = new byte[count]; } private int SocketID = 0; private int SocketLimit; private Socket? ServerSocket; private List ClientSockets = new List(); public delegate void ServerCallback(object o); private ServerCallback? ConnectionCallback; private ServerCallback? ReceiveCallback; private bool Active = false; public enum ServerState { Error, Start, Stop }; public ServerState StartServer(int Port, int Limit, ServerCallback Connection, ServerCallback Receive) { if (Active) { ServerSocket?.Close(); foreach (ClientData c in ClientSockets) { try { c.workSocket?.Shutdown(SocketShutdown.Both); } catch { } c.workSocket?.Close(); } ClientSockets.Clear(); return ServerState.Stop; } ConnectionCallback = Connection; ReceiveCallback = Receive; SocketLimit = Limit; IPEndPoint ip = new(IPAddress.Any, Port); ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { ServerSocket.Bind(ip); ServerSocket.Listen(10); ServerSocket.BeginAccept(new AsyncCallback(AcceptCallback), ServerSocket); Active = true; } catch { ServerSocket.Close(); return ServerState.Error; } return ServerState.Start; } public void AcceptCallback(IAsyncResult ar) { Socket listener = (Socket)ar.AsyncState; if (listener == null) return; Socket handler; try { handler = listener.EndAccept(ar); } catch{ ServerSocket?.Close(); Active = false; return; } if (SocketLimit > ClientSockets.Count) { ClientData clientData = new ClientData(); clientData.ID = ++SocketID; clientData.workSocket = handler; ClientSockets.Add(clientData); ConnectionCallback(new ConnectData { ID = clientData.ID, Connect = true, Count = ClientSockets.Count, Client = handler }); handler.BeginReceive(clientData.buffer, 0, ClientData.count, 0, new AsyncCallback(ReadCallback), clientData); } else handler.Close(); listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); } public void ReadCallback(IAsyncResult ar) { ClientData cd = (ClientData)ar.AsyncState; if (cd == null) return; int bytes = 0; try { bytes = cd.workSocket.EndReceive(ar); } catch { } if (bytes == 0) { cd.workSocket?.Close(); ClientSockets.Remove(cd); ConnectionCallback(new ConnectData { ID = cd.ID, Connect = false, Count = ClientSockets.Count, Client = null }); return; } ReceiveCallback(new ReceiveData { ID = cd.ID, Buffer = cd.buffer, Size = bytes, Client = cd.workSocket }); try { cd.workSocket?.BeginReceive(cd.buffer, 0, ClientData.count, 0, new AsyncCallback(ReadCallback), cd); } catch { } } } }