【发布时间】:2016-08-24 00:08:20
【问题描述】:
我正在使用 C# 调用一个简单的 iis、php、json api。我通过IP调用它,并手动传递主机头,如下
var webhost = "api.srv.com";
var webhostip = <get ip from my own dns cache>;
var client = new WebClient();
client.Headers.Add( "Host", webhost );
response = client.DownlodData("https://" + webhostip + "/etcetc.php");
我正在使用我在应用程序中内置的更可靠的 dns 缓存。我不想受不良 DNS 服务器/配置的摆布。
这行得通。 99% 的时间(请求运行非常频繁)。不过,我会随机收到 400 个错误请求。 logfiles\HTTPERR 显示“-主机名-”的原因
client.DownloadData 使用标准的 fqdn URL 并且没有自定义标头可靠地工作(DNS 失败时除外)
为了比较这两种类型的请求,我将客户端指向/phpinfo.php
没有区别。
这种方法怎么会在 99% 的情况下都有效但随机失败?
编辑:“DNS 缓存”总是返回 IP,我确信这一点。
更新:我改进了日志记录,这是当时的响应和请求数据
请求:https://1.2.3.4/apidir/script.php?p1=xxxx&p2=xx%20xxx
标头:'Host': 'api.srv.com:445'
响应,摘自WebException.Response.GetResponseStream:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Hostname</h2>
<hr><p>HTTP Error 400. The request hostname is invalid.</p>
</BODY></HTML>
此请求每分钟运行一次,只是偶尔失败!
请求时间通常为 60 - 90 秒。 WebClient 的超时时间为 100 秒。使用正常的 fqdn 方法时,我确实会出现超时,但它们从不显示为 400。
更新:我启用了登录功能,以便在问题发生时捕获完整的跟踪信息。
在其中几个之后(由于我国的互联网非常好):
System.Net Error: 0 : [2776] Exception in HttpWebRequest#50710248::GetResponse - Unable to connect to the remote server.
at System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6)
at System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback)
at System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest)
我让连接池尝试重新建立连接(Keep-Alive 很明显),但它无法使用我指定的标头。
System.Net Information: 0 : [2776] ConnectStream#5673090 - Sending headers
Host: 1.2.3.4:445
Connection: Keep-Alive
我怀疑存在 .Net WebClient 错误。
【问题讨论】:
-
随机错误是纯粹的邪恶:)
-
您告诉我们不要质疑或询问您的自定义 dns 缓存...我们应该如何帮助您?包含代码。
-
是的,IP 总是被退回,我确信这一点。我只是开玩笑-显然应该修复 DNS,但这不是一种选择,我希望我的应用程序不会受到不良网络的影响
-
可能是一个问题 - 当使用正常的 fqdn url 时,无论出于何种原因,它都不会显示它的自身 - 查询参数之一中存在空格。我已经修复了,替换为 %20,我会看看周末的情况
-
@JoeyEng 它是ProtocolError,但是你需要检查状态码。 var WE = (WebException)E;var httpResponse = ((HttpWebResponse)WE.Response); (int)httpResponse.StatusCode