using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using Holo.Virtual.Users;
namespace Holo.Socketservers
{
///
/// Asynchronous socket server for the game connections.
///
public static class gameSocketServer
{
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.
///
internal static bool Init(int bindPort, int maxConnections)
{
_Port = bindPort;
_maxConnections = maxConnections;
_activeConnections = new HashSet();
socketHandler = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Out.WriteLine("Starting up asynchronous socket server for game connections for port " + bindPort + "...");
try
{
socketHandler.Bind(new IPEndPoint(IPAddress.Any, bindPort));
socketHandler.Listen(25);
socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler);
Out.WriteLine("Asynchronous socket server for game connections running on port " + bindPort);
Out.WriteLine("Max simultaneous connections is " + maxConnections);
return true;
}
catch
{
Out.WriteError("Error while setting up asynchronous socket server for game connections on port " + bindPort);
Out.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 connectionSocket = ((Socket)iAr.AsyncState).EndAccept(iAr);
Out.WriteLine("Accepted connection [" + connectionID + "] from " + connectionSocket.RemoteEndPoint.ToString().Split(':')[0]);
_activeConnections.Add(connectionID);
_acceptedConnections++;
virtualUser newUser = new virtualUser(connectionID, connectionSocket);
}
}
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);
Out.WriteLine("Flagged connection [" + connectionID + "] as free.");
}
}
internal static int maxConnections
{
///
/// Gets or set an Integer for the maximum amount of connections at the same time.
///
get
{
return _maxConnections;
}
set
{
_maxConnections = value;
}
}
internal static int acceptedConnections
{
///
/// Returns as integer of the accepted connections count since init.
///
get { return _acceptedConnections; }
}
}
}