I have a working tcp server. My problem is that when I call the TCPListener Stop() method I get and exception (Cannot access a disposed object) on TCPClient. And I guess it make sense that it throws the exception, because I closed the Listner so it disposed all the objects that it had. But then async method AcceptTcpClientAsync() finishes and that throws the exception. (that is my guess why is it happening). But I have no idea how to fix this problem.
All the code is available on https://github.com/xszaboj/tcpserver in branch async2.
The exception is thrown in TcpServer class.
public class TcpServer
{
private bool _running = true;
TcpListener _serverSocket;
private ClientHandler _handler;
public async void Start()
{
_running = true;
_handler = new ClientHandler();
_serverSocket = new TcpListener(GetIP(), 8889);
_serverSocket.Start();
while (_running)
{
try
{
TcpClient tcpClient = await _serverSocket.AcceptTcpClientAsync();
Task t = Process(tcpClient);
await t;
}
catch (Exception)
{
//Just suppress exception
}
}
}
private async Task Process(TcpClient tcpClient)
{
try
{
NetworkStream networkStream = tcpClient.GetStream();
StreamReader reader = new StreamReader(networkStream);
while (true)
{
string request = await reader.ReadLineAsync();
if (request != null)
{
_handler.ExecuteCommand(request);
}
else
break; // client closede connection
}
tcpClient.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
if (tcpClient.Connected)
tcpClient.Close();
}
}
public void Stop()
{
_running = false;
_serverSocket.Stop();
}
private IPAddress GetIP()
{
string hostName = Dns.GetHostName();
IPHostEntry ipHostInfo = Dns.GetHostEntry(hostName);
foreach (IPAddress address in ipHostInfo.AddressList)
{
if (address.AddressFamily == AddressFamily.InterNetwork)
{
return address;
}
}
return null;
}
}
Just where it says //Just suppress exception This exception is thrown after you call the Stop() method.
Thanks for any suggestions how to improve this solution.