Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# http listener not listening on localhost, only works with FQDN

(Please remove the close votes. IMHO this is a valid question, all necessary information is provided and yet tried to brief with all necessary information that's required to identify the possible source of the problem).

I'm new to C# coming from the Java world. I try to get a simple http server to listen on a port (in my case 8080) on localhost.

I followed this blog post https://codehosting.net/blog/BlogEngine/post/Simple-C-Web-Server.aspx.

When I run the program, it says

enter image description here

but I cannot reach http://localhost:8080/test/ via browser and netstat does not show port 8888 either. The port is also not blocked by firewall.

Generally, I can run other servers, such as Tomcat, on that port, without a problem. The port is not blocked or used by other applications when I run the C# http server program.

The code:

Program.cs:

static void Main(string[] args)
{
    WebServer ws = new WebServer();
    ws.Run();
    Console.WriteLine("A simple webserver. Press a key to quit.");
    Console.ReadKey();
    ws.Stop();  
}

WebServer.cs:

namespace WebServerTest
{
    public class WebServer
    {
        private readonly HttpListener _listener = new HttpListener();
        private readonly Func<HttpListenerRequest, string> _responderMethod;

        public WebServer()
        {
            if (!HttpListener.IsSupported)
                throw new NotSupportedException(
                    "Needs Windows XP SP2, Server 2003 or later.");

            _listener.Prefixes.Add("http://localhost:8080/test/");
            _responderMethod = SendResponse;
            _listener.Start();
        }

        public static string SendResponse(HttpListenerRequest request)
        {
            return string.Format("<HTML><BODY>My web page.<br>{0}</BODY></HTML>", DateTime.Now);
        }

        public void Run()
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                Console.WriteLine("Webserver running...");

                    while (_listener.IsListening)
                    {
                        ThreadPool.QueueUserWorkItem((c) =>
                        {
                            var ctx = c as HttpListenerContext;

                            string rstr = _responderMethod(ctx.Request);
                            byte[] buf = Encoding.UTF8.GetBytes(rstr);
                            ctx.Response.ContentLength64 = buf.Length;
                            ctx.Response.OutputStream.Write(buf, 0, buf.Length);


                        }, _listener.GetContext());
                    }


            });
        }

        public void Stop()
        {
            _listener.Stop();
            _listener.Close();
        }
    }
}

=========== Update ===========

  • I changed the port to 8080
  • all try-catch-blocks in the code are removed
  • I made sure that the port is not an issue: I tested to run Tomcat servlet container on port 8080 and it works fine (of course, now it's stopped again)
  • Port 8080 is not blocked by any other application nor Firewall

This is what happens when I start the application:

netstat -na | find "8080"

C:\>netstat -na | find "8080"
  TCP    10.10.1.177:8080       0.0.0.0:0              LISTENING
  TCP    192.168.56.1:8080      0.0.0.0:0              LISTENING
  TCP    192.168.99.1:8080      0.0.0.0:0              LISTENING

I don't understand why nothing is listening at 0.0.0.0:8080 (as it is the case for example when I run Tomcat on port 8080), but on those other IPs.

However, I cannot access the http server via localhost...

enter image description here

..or when I try to access via those IP addresses, it's return a "Bad Request" response but not

enter image description here

I also tried other ports such as 7777 or higher ones 10888.

ipconfig:

C:\>ipconfig

Windows-IP-Konfiguration

Ethernet-Adapter Ethernet:

   Verbindungsspezifisches DNS-Suffix: mycompany.ch
   Verbindungslokale IPv6-Adresse  . : fe80::5511:3eb5:408a:2562%4
   IPv4-Adresse  . . . . . . . . . . : 10.10.1.177
   Subnetzmaske  . . . . . . . . . . : 255.255.254.0
   Standardgateway . . . . . . . . . : 10.10.0.1

Drahtlos-LAN-Adapter WiFi:

   Medienstatus. . . . . . . . . . . : Medium getrennt
   Verbindungsspezifisches DNS-Suffix: mycompany.ch

Ethernet-Adapter VirtualBox Host-Only Network:

   Verbindungsspezifisches DNS-Suffix:
   Verbindungslokale IPv6-Adresse  . : fe80::b4b0:6fc5:d0fc:1c77%24
   IPv4-Adresse  . . . . . . . . . . : 192.168.56.1
   Subnetzmaske  . . . . . . . . . . : 255.255.255.0
   Standardgateway . . . . . . . . . :

Ethernet-Adapter VirtualBox Host-Only Network #2:

   Verbindungsspezifisches DNS-Suffix:
   Verbindungslokale IPv6-Adresse  . : fe80::b0e6:32c8:fc0a:af52%25
   IPv4-Adresse  . . . . . . . . . . : 192.168.99.1
   Subnetzmaske  . . . . . . . . . . : 255.255.255.0
   Standardgateway . . . . . . . . . :

VirtualBox Adapters should not be a problem for that program, right?

=============

Just to compare it - running a Tomcat on port 8080 on my PC works fine, just like this:

C:\>netstat -na | find "8080"
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING
  TCP    [::]:8080              [::]:0                 LISTENING

enter image description here

=========== Update 2 ===========

I changed the hostname from localhost to the FQDN:

_listener.Prefixes.Add("http://devml-nb01-81.mycompany.ch:8080/test/");

This way it works.

enter image description here

But why would it not work via localhost (such as Tomcat?)

C:\>ping localhost

Ping wird ausgeführt für devml-nb01-81.mycompany.ch [::1] mit 32 Bytes Daten:
Antwort von ::1: Zeit<1ms
Antwort von ::1: Zeit<1ms
Antwort von ::1: Zeit<1ms
Antwort von ::1: Zeit<1ms

Ping-Statistik für ::1:
    Pakete: Gesendet = 4, Empfangen = 4, Verloren = 0
    (0% Verlust),
Ca. Zeitangaben in Millisek.:
    Minimum = 0ms, Maximum = 0ms, Mittelwert = 0ms
like image 976
Mathias Conradt Avatar asked Apr 25 '16 16:04

Mathias Conradt


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.


1 Answers

Open an elevated command prompt and try

netsh http add urlacl url=http://+:8080/ user=EVERYONE

(You'll need to use the localized name for EVERYONE or the SID which is global.)

Applications that use HTTP.sys need reservations. You can read more about that here.

By the way, localhost is often problematic in other ways (e.g. some OAuth providers don't allow it). One way around that is to use one of the DNS names that has been mapped to 127.0.0.1 like vcap.me. You can put any name in front: foo.vcap.me and it resolves to 127.0.0.1.

like image 91
Ian Mercer Avatar answered Sep 30 '22 01:09

Ian Mercer