C# .Net HttpListener.GetContext()给出;503“服务不可用”;给客户

C# .Net HttpListener.GetContext()给出;503“服务不可用”;给客户,c#,.net,httplistener,C#,.net,Httplistener,我试图用C#编写一个非常简单的自定义Http服务器 实现连接的代码与.Net提供的代码一样简单: // get our IPv4 address IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName()); IPAddress theAddress = localIPs.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault(

我试图用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;
运行此操作时,
GetContext()
阻塞,永远不会返回,也不会引发异常

listener.Start()有效——URL已正确保留给具有“netsh http add urlacl…”的正确用户,否则Start()将抛出。URL也只保留一次

我可以看到netstat-na正在监听端口

我试图通过浏览器或
wget
cygwin
实现来访问此文件。两者都告诉我“错误503:服务不可用。”

以下是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.
这意味着TCP连接已经建立,但HttpListener.GetContext()并不费心为请求提供服务并提供上下文,它也不费心至少抛出一个异常来告诉我出了什么问题。它只是关闭了连接。从调试输出来看,它甚至没有第一次机会捕获自身的异常

我上下搜索了网络,没有发现任何有用的东西

Windows事件日志中没有错误

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

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

有人知道
GetContext()
中可能出现的错误以及我如何调试或解决这个问题吗

======


编辑:我已启用.Net Framework源代码步进,并已步进GetContext()。阻止和拒绝服务http请求发生在一个叫做“UnsafeNclNativeMethods.HttpApi.HttpReceiveHttpRequest”的东西中,我猜,它可能是在中记录的本机HttpReceiveHttpRequest方法。因此,是本地API拒绝了我的请求。

我没有找到解决方案,但找到了一个解决方法

有趣的是,如果我更深入一层并使用纯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);

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

我只是遇到了同样的问题,它是由URL ACL引起的

从提升的命令提示符

netsh http show urlacl
将显示所有URL ACL

netsh http://+:1234/
将删除URL为
http://+:1234/

netsh http add urlacl url=http://+:1234/user=Everyone
将添加一个url ACL,任何本地用户都可以监听(通常应使用网络服务帐户)

此URL需要与
HttpListener
中的前缀匹配

如果您只在本地主机上侦听,则不需要URL ACL


通常没有正确的URL ACL会导致启动侦听器时出现权限错误。我不确定是什么具体情况导致它通过此操作,然后返回503 Service Unavailable on
GetContext

我尝试了您的示例,它对我有效,但我有Win7。您尝试过吗:?谢谢,csharpfolk,是的,我尝试过。这就是我在写“我上下搜索了…Stackoverflow,没有找到任何有用的东西”时的意思,这也是为什么我提到URL保留是正确的,没有加倍。我已经使用了几个前缀。@JS,您能提供有关错误的详细信息吗?内部服务器堆栈跟踪,检查InnerException属性(如果可用)。我需要更多的信息。另外,你有没有尝试在本地IIS下运行?谢谢,安东·诺科:正如我在帖子中所说的,没有抛出异常。因此,没有堆栈跟踪,没有内部异常。而不是在IIS下,当我说“像.Net提供的那样简单”时,这就是我想说的。这意味着上下文是一个简单的开箱即用的控制台应用程序,它几乎不包含任何其他代码。我希望我能提供更详细的信息。
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