I have the following async TCP server that I use to accept incoming requests from clients that want to upload files. After say about 1-4 hours, the server simply stops accepting any new connections. This has been baffling me because I am unable to reproduce the error deterministically. The rest of the threads in my program continue to function properly. There are no exceptions thrown whatsoever. Any suggestions on what could be happening?
Before the server goes dead, all I do see is that it manages to finish the pending requests and then stops. I have a hunch that the server is experiencing frequent network disconnects. How do I make this piece of code more robust to failures? I've added try-catch to both pieces of code that might fail but I feel I'm still missing something.
I setup another thread to check if this server releases the socket but it seems like the socket is in use even after it stops processing client requests. I verified this using netstat -a
internal class TCPServer
{
private readonly int _listeningPort;
private TcpListener listener;
public TCPServer(int port)
{
_listeningPort = port;
listener = new TcpListener(IPAddress.Any, _listeningPort);
listener.Start(int.MaxValue);
}
public async void Start()
{
while (true)
{
Log.Verbose("Waiting for connections...");
try
{
var tcpClient = await listener.AcceptTcpClientAsync();
Task t = HandleConnectionAsync(tcpClient);
await t;
}
catch (Exception exp)
{
Log.Fatal(exp.ToString());
}
}
}
private async Task HandleConnectionAsync(TcpClient tcpClient)
{
try
{
string outputFile = ""; // get a random string
using (var stream = tcpClient.GetStream())
using (var output = File.Create(outputFile))
{
//...
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
// ...
await output.WriteAsync(buffer, 0, bytesRead);
}
}
tcpClient.Close();
}
catch (Exception exp)
{
Log(exp.Message);
}
}