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; }
}
}
}