Получение сообщения “базовое соединение было закрыто” в HttpWebRequest
-
29-09-2019 - |
Вопрос
У меня есть заявление, написанное на VB.NET (НЕТ asp.net , это консольное приложение для Windows).Я пытаюсь вызвать URL-адрес (html-страницу) и вернуть ответ в виде строки.Ответ - это прямой JSON, без каких-либо html-тегов вообще.Она открывается словами {
и завершается словами }
.
Я создаю объект HttpWebRequest нормально.Тогда звони req.GetResponse()
.Как только я это делаю, я получаю сообщение об ошибке The underlying connection was closed: The connection was closed unexpectedly.
Я погуглил и проверил 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 SO разберет их правильно) - это все, что я пробовал до сих пор, основываясь на том, что я нашел в Интернете.Никто из них этого не исправил.Я проверил, что создаваемый URL-адрес правильный;если я вызываю точно такой же URL-адрес в своем браузере, он выдает точно такой же ожидаемый ответ.
Я пробовал подключать его к сети...и я вижу, что фактические ожидаемые, полные данные возвращаются в выходных данных shark, а затем несколько строк, а затем красную строку с надписью:http > 51943 [RST] Seq=1607 Win=0 Len=0
это последняя строка, которая появляется перед тем, как .NET выдает ошибку.
Я также попробовал включить System.Net
отслеживание / протоколирование по сообщению здесь, на SO, и в выходном файле из этого я вижу аналогично все ожидаемые данные JSON делает вернуться, но после того, как он вернется, он добавит эти строки в .Журнал трассировки СЕТИ:
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-адрес для использования.
Две вещи, которые действительно сбивают меня с толку, это то, что
а) он отлично работает при вызове в браузере
б) как WireShark, так и .NET tracing показывают все фактические данные ЯВЛЯЕТСЯ возвращаюсь, а фреймворк по какой-то причине отключается ПОСЛЕ получения всех данных!
Само 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()
- также выдает ту же ошибку о закрытии соединения.
Решение
Можете ли вы опубликовать все содержимое журнала трассировки на pastebin.com и разместить ссылку здесь?
Возможно, вы получаете это исключение, потому что сервер может сказать в заголовке "Content-Length", что он отправляет N байт объекта, но на самом деле отправляет меньше N байт и закрывает соединение.
Ответ:
Спасибо за предоставленные данные.Из журнала трассировки и wireshark trace кажется, что сервер не отправляет никаких заголовков ответов, а напрямую отправляет данные.Это нарушение протокола HTTP.Вот почему клиент выдает исключение.
Другие советы
Вот как я заставил это работать...Спасибо ферозе за то, что указала мне правильное направление!
(начисленные баллы)
Public Function GetJSON(ByRef d As db.Device) As Boolean
Try
Dim tcp = New TcpClient()
tcp.Connect(d.IpAddress, 80)
Dim ns = tcp.GetStream()
Dim req As Byte() = System.Text.Encoding.ASCII.GetBytes(
"GET /getdata.htm HTTP/1.1" & vbCrLf & vbCrLf
)
ns.Write(req, 0, req.Length)
Dim rsp(2048) As Byte, rcv As Integer
Do
rcv = ns.Read(rsp, 0, rsp.Length)
d.JSON &= System.Text.Encoding.ASCII.GetString(rsp, 0, rcv)
Loop Until rcv = 0
tcp.Close()
Return True
Catch ex As Exception
Log(ex.Message)
Return False
End Try
End Function
Это помогает мне.Я надеюсь, что это тоже кому-то поможет.
Сразу после создания объекта HttpWebRequest добавьте эту строку.
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
Это означает, что в качестве протокола безопасности используется уровень защищенных сокетов (SSL) 3.0
Проверьте задержку выполнения запроса.Если это больше нескольких мс, то стоит отключить алгоритм Нэгла
ServicePointManager.UseNagleAlgorithm = false;
У меня была такая же проблема, связанная с запросом БЕЗ тела.В моем случае, установив ContentLength
до НУЛЯ устранил проблему.
В моем случае проблема заключалась в том, что мы использовали "http: //.." в качестве адреса службы вместо "https: //"...