簡體   English   中英

.Net HttpListener.GetContext()為客戶端提供“503 Service Unavailable”

[英].Net HttpListener.GetContext() gives “503 Service Unavailable” to the client

我想在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() 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 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正在監聽端口。

我試圖通過瀏覽器或wgetcygwin實現來訪問它。 兩者都給我"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.

這意味着TCP連接已建立,但HttpListener.GetContext()並不打算為請求提供服務並給我上下文,它也至少不會拋出異常來告訴我什么是錯誤的。 它只是關閉連接。 從調試輸出來看,它內部甚至沒有First-Chance異常。

我上下搜索了Net和Stackoverflow,但沒有找到任何有用的東西。

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”的內容中,我想這可能是https://msdn.microsoft.com/en-us/library/windows/中記錄的本機HttpReceiveHttpRequest方法。 desktop / aa364495(v = vs.85).aspx 所以它是拒絕我的請求的本機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);

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

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

因此,作為一種解決方法,我可以實現我自己的http請求解析器和響應生成器...而不是我喜歡被迫重新發明輪子。

我剛遇到同樣的問題,它是由URL ACL引起的。

從提升的命令提示符

netsh http show urlacl將顯示所有URL ACL

netsh http delete urlacl http://+:1234/將使用URL http://+:1234/刪除URL ACL

netsh http add urlacl url=http://+:1234/ user=Everyone都會添加一個任何本地用戶都可以監聽的URL ACL(通常這應該使用網絡服務帳戶)

此URL需要與HttpListener中的前綴匹配。

如果您只是在偵聽localhost,則不需要URL ACL。

通常,沒有正確的URL ACL會在啟動偵聽器時導致權限錯誤。 我不確定具體情況是什么導致它超過此但是然后在GetContext上返回503服務不可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM