'Trying to setup HttpListener causes an exception, any ideas?

I'm trying to set up a HttpListener for a Server Manager for my Multiplayer Unity Game but I am getting an exception when executing the following code:

using System;
using System.IO;
using System.Net;
using System.Threading;
using WebAPI.Route;
using System.Collections.Generic;
using System.Linq;

namespace WebAPI
{
public class WebListener
{
    private int Port = 4444;

    private HttpListener Listener;
    private Thread ListenerThread;
    private bool Bailout = false;

    private List<IRouteController> Routes;

    public WebListener(int port, List<IRouteController> routes)
    {
        Port = port;
        Routes = routes;

        string ip = Dns.GetHostEntry(Dns.GetHostName())
            .AddressList
            .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            .ToString();

        Listener = new HttpListener();
        Listener.Prefixes.Add("http://localhost:" + Port + "/");
        Listener.Prefixes.Add("http://127.0.0.1:" + Port + "/");
        Listener.Prefixes.Add("http://" + ip + ":" + Port + " /");
        Listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
        Listener.Start();

        ListenerThread = new Thread(Listen);
        ListenerThread.Start();
    }

    ~WebListener()
    {
        Bailout = true;
        if (ListenerThread != null)
            ListenerThread.Join();
    }

    private void Listen()
    {
        while (!Bailout)
        {
            var result = Listener.BeginGetContext(ListenerCallback, Listener);
            result.AsyncWaitHandle.WaitOne();
        }
    }

    private void ListenerCallback(IAsyncResult result)
    {
        var context = Listener.EndGetContext(result);

        if (context.Request.HttpMethod == "POST")
        {
            string route = context.Request.Url.LocalPath.ToLower();

            var controller = Routes.Where(r => route.Contains(r.GetRoute())).FirstOrDefault();
            if (controller != null)
            {
                var json = new StreamReader(context.Request.InputStream,
                                            context.Request.ContentEncoding).ReadToEnd();

                controller.RecieveRequest(json);
            }
            else
            {
                WebLogger.LogWarning("Invalid route, no matching controller found: " + route);
            }
        }

        context.Response.Close();
    }

}
}

This is the exception I receive on line Listener.Start();

Exception thrown: 'System.Net.HttpListenerException' in System.Net.HttpListener.dll The parameter is incorrect.

I'm not sure what I'm doing wrong, any ideas?



Solution 1:[1]

The " /" in your last Prefixes.Add leads to your exception.

Listener.Prefixes.Add("http://" + ip + ":" + Port + " /");
//                                                   ^  this space above

But if you change it to

Listener.Prefixes.Add("http://" + ip + ":" + Port + "/");

You may get an Access Denied exception if you run your application without admin privileges and did not already add the access rights to all of your prefixes for your user with netsh. Read here for more information.

Instead of adding the Prefixes one by one, you can use wildcards like "http://*:" + Port + "/" or "http://+:" + Port + "/". With the wildcards you don't need to to get a IPv4 address from your AddressList which may not be the interface you want to bind to.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1