获取“底层连接已关闭”在 HttpWebRequest 上
我有一个用 VB.NET 编写的应用程序(不是 asp.net,它是一个 Windows 控制台应用程序)。我试图调用一个 url (一个 html 页面)并将响应返回到一个字符串中。响应是直接的 JSON,没有任何 html 标签。它以 {
开始,以 }
结束。
我很好地创建了 HttpWebRequest 对象。然后调用 req.GetResponse()
。一旦我这样做,我就会收到错误底层连接已关闭:连接意外关闭。
我一直在谷歌搜索并检查stackoverflow,并尝试了我发现的所有适用的方法(很多)其中与 WCF 服务配置有关,但不适用)。
这是我的代码:
Public Function GetJSON(ByRef d As db.Device) As Boolean
Try
d.Url = "http://" & d.IpAddress & ini.doc.<svc>.<url>.Value
Dim req As HttpWebRequest = HttpWebRequest.Create(d.Url)
// req.Accept = "*/*"
// req.Timeout = 30000
// req.ReadWriteTimeout = 30000
// req.KeepAlive = False
// req.UseDefaultCredentials = True
// req.CachePolicy = HttpWebRequest.DefaultCachePolicy
// req.Proxy = HttpWebRequest.DefaultWebProxy
// req.ProtocolVersion = New System.Version(1, 0)
Dim rsp As HttpWebResponse = req.GetResponse()
Return True
Catch ex As Exception
Log(ex.Message)
Return False
Finally
rsp = Nothing
req = Nothing
End Try
End Function
注释掉的行(错误的注释风格,但SO会正确解析它)是我迄今为止根据我在网上找到的内容尝试过的所有内容。他们都没有修复它。我已经验证正在构建的 URL 是正确的;如果我在浏览器中调用完全相同的 URL,它会返回完全正确的预期响应。
我尝试过对它进行wireshark...我看到实际预期的完整数据返回到鲨鱼输出中,然后是几行,然后是一条红线,上面写着: http> 51943 [RST] Seq=1607 Win=0 Len=0
这是 .NET 引发错误之前显示的最后一行。
我还尝试根据 SO 上的一篇文章打开 System.Net
跟踪/日志记录,并且在输出文件中我看到类似的所有预期 JSON 数据确实都回来了,但返回后,它会在 .NET 跟踪日志中抛出这些行:
System.Net.Sockets Verbose: 0 : [7040] Exiting Socket#60467532::Receive() -> 1605#1605
System.Net.Sockets Verbose: 0 : [7040] Socket#60467532::Receive()
System.Net.Sockets Verbose: 0 : [7040] Data from Socket#60467532::Receive
System.Net.Sockets Verbose: 0 : [7040] 00000000 : :
System.Net.Sockets Verbose: 0 : [7040] Exiting Socket#60467532::Receive() -> 0#0
System.Net.Sockets Verbose: 0 : [7040] Socket#60467532::Dispose()
System.Net Error: 0 : [7040] Exception in the HttpWebRequest#27806816:: - The underlying connection was closed: The connection was closed unexpectedly.
System.Net Error: 0 : [7040] Exception in the HttpWebRequest#27806816::GetResponse - The underlying connection was closed: The connection was closed unexpectedly.
有什么想法下一步该去哪里尝试解决这个问题吗?我们正在从一些环境监测传感器设备中读取这些数据,他们给了我们这个 URL 供我们使用。
真正让我困惑的两件事是
a)在浏览器中调用时它工作得很好
b) WireShark 和 .NET 跟踪都显示所有实际返回的数据IS,并且框架由于某种原因在收到所有数据后出现异常!
WebException 本身很少用,因为它的 InnerException 为 null 并且它的状态只是显示“ConnectionClosed {8}”
提前致谢!
更新 08/18 1130: 我现在也尝试过仅使用 System.Net.WebRequest
而不是 HttpWebRequest
。这也没有什么区别。
更新 08/18 1222: 我只是尝试切换我的代码,而不是使用 [Http]Web[Request|Response]
来调暗 WebClient
对象并使用其 DownloadString()
方法。然而,这也会抛出同样的错误。
更新 08/18 1230: 尝试使用 My.Computer.Network.DownloadFile()
- 也遇到相同的连接关闭错误。
I have an application written in VB.NET (NOT asp.net, it is a Windows Console app). I am trying to call a url (an html page) and get back the response into a string. The response is straight JSON, no html tags whatsoever. It opens with {
and closes with }
.
I create the HttpWebRequest object fine. Then call req.GetResponse()
. As soon as I do this I get the error The underlying connection was closed: The connection was closed unexpectedly.
I've been googling and checking stackoverflow, and tried everything I've found that applies (a lot of it has to do with WCF service configurations, which don't apply).
Here is my code:
Public Function GetJSON(ByRef d As db.Device) As Boolean
Try
d.Url = "http://" & d.IpAddress & ini.doc.<svc>.<url>.Value
Dim req As HttpWebRequest = HttpWebRequest.Create(d.Url)
// req.Accept = "*/*"
// req.Timeout = 30000
// req.ReadWriteTimeout = 30000
// req.KeepAlive = False
// req.UseDefaultCredentials = True
// req.CachePolicy = HttpWebRequest.DefaultCachePolicy
// req.Proxy = HttpWebRequest.DefaultWebProxy
// req.ProtocolVersion = New System.Version(1, 0)
Dim rsp As HttpWebResponse = req.GetResponse()
Return True
Catch ex As Exception
Log(ex.Message)
Return False
Finally
rsp = Nothing
req = Nothing
End Try
End Function
The commented out lines (wrong comment style, but so SO will parse it right) are all the things I have tried so far based on what I've found online. None of them fixed it. I have verified that the URL being built is correct; if I call the exact same URL in my browser it gives back exactly the right expected response.
I've tried wiresharking it... and i see the actual expected, complete data come back in the shark output, and then a few lines, and then a red line which says:http > 51943 [RST] Seq=1607 Win=0 Len=0
which is the last line to show up before .NET is throwing the error.
I also tried turning on System.Net
tracing/logging per a post here on SO, and in the output file from that I see similarly all the expected JSON data does come back, but after it comes back it throws these lines in the .NET trace log:
System.Net.Sockets Verbose: 0 : [7040] Exiting Socket#60467532::Receive() -> 1605#1605
System.Net.Sockets Verbose: 0 : [7040] Socket#60467532::Receive()
System.Net.Sockets Verbose: 0 : [7040] Data from Socket#60467532::Receive
System.Net.Sockets Verbose: 0 : [7040] 00000000 : :
System.Net.Sockets Verbose: 0 : [7040] Exiting Socket#60467532::Receive() -> 0#0
System.Net.Sockets Verbose: 0 : [7040] Socket#60467532::Dispose()
System.Net Error: 0 : [7040] Exception in the HttpWebRequest#27806816:: - The underlying connection was closed: The connection was closed unexpectedly.
System.Net Error: 0 : [7040] Exception in the HttpWebRequest#27806816::GetResponse - The underlying connection was closed: The connection was closed unexpectedly.
Any ideas where to go next to try to figure this out? We are reading this data out of some environmental-monitoring sensor devices, and they gave us this url to use.
Two things that really get me and confuse me on this are that
a) it works perfectly fine when called in a browser
b) both WireShark and .NET tracing show all the data actually IS coming back, and the framework is for some reason excepting AFTER receiving all the data!
The WebException itself is being very little use, as its InnerException is null and its Status just says "ConnectionClosed {8}"
Thanks in advance!!!
UPDATE 08/18 1130: I have also tried now using just System.Net.WebRequest
as opposed to HttpWebRequest
. This did not make any difference either.
UPDATE 08/18 1222: I just tried switching my code instead of using [Http]Web[Request|Response]
to dimming up a WebClient
object instead and using its DownloadString()
method. This however also throws the same exact error.
UPDATE 08/18 1230: Tried using My.Computer.Network.DownloadFile()
- also gets the same connection closed error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您能否将跟踪日志的全部内容发布到pastebin.com 上并在此处发布链接?
您可能会收到此异常,因为服务器可能会在“Content-Length”标头中说它正在发送 N 个字节的实体,但实际上发送的长度少于 N 个字节并关闭连接。
答:
谢谢你提供的数据。从tracelog和wireshark跟踪来看,服务器似乎没有发送任何响应头,而是直接发送数据。这是违反 HTTP 协议的行为。这就是客户端抛出异常的原因。
Can you post the entire contents of the trace log on pastebin.com and post a link here?
You might be getting this exception because the server might say in "Content-Length" header that it is sending N bytes of entity, but is actually sending less than N bytes and closing the connection.
Answer:
Thanks for the data. From the tracelog and wireshark trace, it seems that the server is not sending any response headers, and directly sending the data. This is a HTTP protocol violation. That is why the client is throwing the exception.
这对我有帮助。我希望它也能帮助别人。
创建 HttpWebRequest 对象后,
添加这一行。
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
它的含义是将安全套接字层 (SSL) 3.0 指定为安全协议
http://support.microsoft.com /kb/915599
This helps me. I hope it helps someone as well.
Right after you create HttpWebRequest Object,
add this line.
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
What it means is specifies the Secure Socket Layer (SSL) 3.0 as security protocol
http://support.microsoft.com/kb/915599
这是我如何让它工作的...感谢 feroze 为我指明了正确的方向!
(授予积分)
Here is how i got it working... Thanks to feroze for pointing me in the right direction!
(points awarded)
检查请求的延迟。如果超过几毫秒,则值得禁用 Nagle 算法
Check the latency of the request. If it is more than a few ms then it is worth disabling the Nagle Algorithm
关于没有正文的请求,我遇到了同样的问题。就我而言,将
ContentLength
设置为零解决了问题。I was having the same issue regarding a request WITHOUT a body. In my case, setting the
ContentLength
to ZERO fixed the problem.就我而言,问题是我们使用“http://..”作为服务地址而不是“https://”...
In my case the problem was we used "http://.." as service address instead of "https://"...
当所需的标头不存在时,我也收到此错误
I have also received this error when a required header wasn't present