using System; using System.Net; using System.Net.Sockets; using System.Collections.Generic; using System.Threading; using Duck.Virtual.Users; namespace Duck.Net.Game { /// /// Asynchronous socket server for the info connections. /// public static class infoSocketServer { private static Socket _socketHandler; private static int _Port; private static int _maxConnections; private static int _acceptedConnections; private static HashSet _activeConnections; /// /// Initializes the socket listener for game connections and starts listening. /// /// The port where the socket listener should be bound to. /// The maximum amount of simultaneous connections. /// The maximum length of the connection request queue. /// internal static bool Init(int bindPort, int maxConnections, int backLog) { _Port = bindPort; _maxConnections = maxConnections; _activeConnections = new HashSet(); _socketHandler = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IO.WriteLine("Starting up socket server for info connections on port " + bindPort + "..."); try { _socketHandler.Bind(new IPEndPoint(IPAddress.Any, bindPort)); _socketHandler.Listen(backLog); _socketHandler.BeginAccept(new AsyncCallback(connectionRequest), _socketHandler); IO.WriteLine("Socket server for info connections running on port " + bindPort + "."); IO.WriteLine("Max simultaneous connections is " + maxConnections + "."); IO.WriteLine("Max length of connection request queue (backlog) is " + backLog + "."); return true; } catch { IO.WriteError("Error while setting up asynchronous socket server for info connections on port " + bindPort); IO.WriteError("Port " + bindPort + " could be invalid or in use already."); return false; } } private static void connectionRequest(IAsyncResult iAr) { try { int connectionID = 0; for (int i = 1; i < _maxConnections; i++) { if (_activeConnections.Contains(i) == false) { connectionID = i; break; } } if (connectionID > 0) { Socket Request = ((Socket)iAr.AsyncState).EndAccept(iAr); IO.WriteLine("Accepted connection [" + connectionID + "] from " + Request.RemoteEndPoint.ToString().Split(':')[0]); _activeConnections.Add(connectionID); _acceptedConnections++; virtualUser Client = new virtualUser(connectionID, Request); } } catch { } _socketHandler.BeginAccept(new AsyncCallback(connectionRequest), _socketHandler); } /// /// Flags a connection as free. /// /// The ID of the connection. internal static void freeConnection(int connectionID) { if (_activeConnections.Contains(connectionID)) { _activeConnections.Remove(connectionID); IO.WriteLine("Flagged connection [" + connectionID + "] as free."); } } /// /// Gets or set an Integer for the maximum amount of connections at the same time. /// internal static int maxConnections { get { return _maxConnections; } set { _maxConnections = value; } } internal static int acceptedConnections { /// /// Returns as integer of the accepted connections count since init. /// get { return _acceptedConnections; } } } }