0

I have a simple C# Windows Service that should respond "OK" to GET requests on port 8080. Everything works fine, with one simple itch...

Every single request made to the service stays in TIME_WAIT. Am I missing something, I've looked around and most samples I've seen on HTTPListeners and Windows Services are doing it in a similar fashion?!

    private HttpListener _listener;

    protected override void OnStart(string[] args)
    {
        _listener = new HttpListener();
        _listener.Prefixes.Add("http://*:8080/");
        _listener.Start();
        _listener.BeginGetContext(new AsyncCallback(OnRequestReceive), _listener);
    }

    protected override void OnStop()
    {
        _listener.Stop();
    }

    private void OnRequestReceive(IAsyncResult result)
    {
        if (!_listener.IsListening)
            return;

        //Get context for a request.
        HttpListenerContext context = _listener.EndGetContext(result);
        HttpListenerRequest request = context.Request;

        //Obtain a response object.
        HttpListenerResponse response = context.Response;
        response.ContentType = "application/json";
        response.KeepAlive = false;

        //Our return message...
        string responseString = "OK";

        //Construct the response. 
        byte[] buffer = Encoding.UTF8.GetBytes(responseString);

        Stream output = response.OutputStream;
        response.ContentLength64 = buffer.Length;
        output.Write(buffer, 0, buffer.Length);

        //Close and send response
        try
        {
            output.Flush();
            output.Close();
            response.Close();
        }
        finally
        {   
            //Wait for another request
            _listener.BeginGetContext(new AsyncCallback(OnRequestReceive), _listener);
        }
    }      

Edit: Fixed Local declaration of _listener.

Milkshake
  • 31
  • 7

1 Answers1

0

Thanks to rene for pointing out the correct direction...

TIME-WAIT (either server or client) represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request. [According to RFC 793 a connection can stay in TIME-WAIT for a maximum of four minutes known as a MSL (maximum segment lifetime).]

For anyone else who wants to change this behavior: The TIME_WAIT period is configurable by modifying the following DWORD registry setting that represents the TIME_WAIT period in seconds.

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters\TcpTimedWaitDelay

Milkshake
  • 31
  • 7
  • 1
    Do note that the setting is there for a reason, though. If old TCP data comes to a port that is already used by a new connection, confusion is bound to occur. You might want to change the maximum number of ephemeral ports instead, for example. And don't set the TimedWaitDelay lower than about 30s, or you might get a lot of errors in practice. – Luaan Oct 29 '14 at 14:00
  • In addition to Luaan's comment, see also this [discusssion on TIME_WAIT and it's effect on busy server](http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/). – CodeFox Sep 25 '16 at 09:30