.Net HttpListener.GetContext()向客户端提供“ 503服务不可用”

J S*_*J S 5 .net c# httplistener

我试图在C#中编写一个非常非常简单的自定义Http服务器。

.Net提供的连接代码很简单:

 // get our IPv4 address
 IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
 IPAddress theAddress = localIPs.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault();

 // Create a http listener.
 var listener = new HttpListener();
 string myUrlPrefix = $"http://{theAddress.ToString()}:{port}/MyService/";
 listener.Prefixes.Add(myUrlPrefix);
 Console.WriteLine($"Trying to listen on {myUrlPrefix}");
 listener.Start();
 Console.WriteLine("Listening...");
 HttpListenerContext context = null;
 try
 {
     context = listener.GetContext();
 }
 catch(Exception ex)
 {
     Console.WriteLine(ex.Message);
 }

 HttpListenerRequest request = context.Request;
Run Code Online (Sandbox Code Playgroud)

运行此命令时,将GetContext()阻塞,从不返回,也不会引发异常。

listener.Start() works -- the URL is properly reserved for the correct user with 'netsh http add urlacl...'., else Start() would throw. The URL is also only reserved once

我可以通过netstat -na查看正在监听的端口。

我正在尝试通过浏览器或的cygwin实现来访问它wget。两者都给我"ERROR 503: Service Unavailable."

这是wget的输出:

$ wget http://127.0.0.1:45987/MyService/
--2016-03-06 14:54:37--  http://127.0.0.1:45987/MyService/
Connecting to 127.0.0.1:45987... connected.
HTTP request sent, awaiting response... 503 Service Unavailable
2016-03-06 14:54:37 ERROR 503: Service Unavailable.
Run Code Online (Sandbox Code Playgroud)

这意味着建立了TCP连接,但是HttpListener.GetContext()并不麻烦服务于请求并为我提供了上下文,它也不必烦恼至少引发异常以告诉我出了什么问题。它只是关闭连接。从调试输出中,它甚至没有捕获自己的First-Chance异常。

我已经上下搜索了Net和Stackoverflow,但没有发现任何有用的信息。

Windows事件日志中没有错误。

这是Windows 10 Pro和Microsoft Visual Studio Community 2015版本14.0.23107.0 D14REL与Microsoft .NET Framework版本4.6.01038。

值得一提的是,我还在关闭所有防火墙的情况下进行了测试,结果仍然相同。

有谁知道这可能出什么问题GetContext()以及如何调试或解决这个问题?

======

编辑:我已启用.Net Framework源代码步进,并已步进到GetContext()。阻止和拒绝服务HTTP请求发生在名为“ UnsafeNclNativeMethods.HttpApi.HttpReceiveHttpRequest”的东西中,我想这可能是https://msdn.microsoft.com/zh-cn/library/windows/中记录的本机HttpReceiveHttpRequest方法桌面/aa364495(v=vs.85).aspx。因此,是本机API拒绝了我的请求。

J S*_*J S 0

我还没有找到解决方案,但找到了解决方法。

有趣的是,如果我更深入地使用纯 TcpListener,我可以毫无问题地以纯文本形式接收请求。

 // Create a Tcp listener.
 mTcpListener = new TcpListener(theAddress, port);

 Console.WriteLine($"Trying to listen on {theAddress}:{port}");
 mTcpListener.Start();
 Console.WriteLine("Listening...");
 Socket socket = null;
 try
 {
     socket = mTcpListener.AcceptSocket();
 }
 catch (Exception ex)
 {
     Console.WriteLine(ex.Message);
     return;
 }
 // wait a little for the socket buffer to fill up
 await Task.Delay(20);

 int bytesAvailable = socket.Available;
 var completeBuffer = new List<byte>();
 while (bytesAvailable > 0)
 {
     byte[] buffer = new byte[bytesAvailable];
     int bytesRead = socket.Receive(buffer);
     completeBuffer.AddRange(buffer.Take(bytesRead));

     bytesAvailable = socket.Available;
 }

 byte[] receivedBytes = completeBuffer.ToArray();

 string receivedString = Encoding.ASCII.GetString(receivedBytes);
Run Code Online (Sandbox Code Playgroud)

... 奇迹般有效。返回的字符串是

GET /MyService/ HTTP/1.1
User-Agent: Wget/1.17.1 (cygwin)
Accept: */*
Accept-Encoding: identity
Host: 127.0.0.1:45987
Connection: Keep-Alive
Run Code Online (Sandbox Code Playgroud)

因此,作为一种解决方法,我可以实现自己的 http 请求解析器和响应生成器......并不是说我喜欢被迫重新发明轮子。