I am currently getting an ObjectDisposedException on the following line.
var client = ((Socket) asyncResult.AsyncState).EndAccept(asyncResult);
System.ObjectDisposedException: 'Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'.'
I was just wondering, what is the right way (in terms of best practice) to avoid an error like this? I'm unsure on how to handle it, how do I check if its disposed before hand, but is that what I should be doing? Or checking something else.
I'm self taught C# so I never learnt things like this, could someone give some insight?
Here is the full class:
internal sealed class SocketHandler : IDisposable
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
private readonly Socket _serverSocket;
public SocketHandler()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Load();
}
public void Dispose()
{
_serverSocket?.Close(); // close also calls dispose...
}
private void Load()
{
var config = Program.Server.ConfigHandler;
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, config.GetConfigValueByKey("network.sockets.port").ToInt()));
_serverSocket.Listen(int.Parse(config.GetConfigValueByKey("network.sockets.backlog")));
_serverSocket.BeginAccept(OnAcceptConnection, _serverSocket);
}
private void OnAcceptConnection(IAsyncResult asyncResult)
{
try
{
if (_serverSocket == null)
{
return;
}
var client = ((Socket) asyncResult.AsyncState).EndAccept(asyncResult);
var playerHandler = Program.Server.BaseHandler.PlayerHandler;
var players = playerHandler.Players;
var config = Program.Server.ConfigHandler;
var maxConnections = int.Parse(config.GetConfigValueByKey("game.players.limit"));
var maxConnectionsPerIp = int.Parse(config.GetConfigValueByKey("game.players.ip_limit"));
if (players.Count >= maxConnections)
{
Logger.Warn("Incoming connection was refused because the player limit was exceeded.");
client.Shutdown(SocketShutdown.Both);
client.Close();
return;
}
if (players.Values.Count(x => x != null && !x._disconnected && x.getIp() == client.RemoteEndPoint.ToString().Split(':')[0]) > maxConnectionsPerIp)
{
Logger.Warn("Incoming connection was refused because the IP limit was exceeded.");
client.Shutdown(SocketShutdown.Both);
client.Close();
return;
}
var clientId = Randomizer.Next(1, 10000);
Program.Server.BaseHandler.PlayerHandler.TryAddPlayer(clientId, new Player(clientId, client, new InitialPacketParser()));
}
catch (SocketException socketException)
{
Logger.Fatal(socketException, "Failed to accept socket connection.");
}
finally
{
_serverSocket?.BeginAccept(OnAcceptConnection, _serverSocket);
}
}
}