Получение «основного соединения было закрыто» в HttpWebRequest

У меня есть приложение, написанное на VB.NET ( НЕ asp.net, это консольное приложение Windows). Я пытаюсь вызвать URL-адрес (HTML-страницу) и получить ответ в виде строки. Ответ прямой JSON, никаких HTML-тегов. Он открывается с { и закрывается с } .

Я прекрасно создаю объект HttpWebRequest. Затем вызовите req.GetResponse () . Как только я это делаю, я получаю сообщение об ошибке Основное соединение было закрыто: Соединение было неожиданно закрыто. Я гуглил и проверял стекопоток, и перепробовал все, что мне удалось найти (во многом это связано с конфигурациями сервисов 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 в моем браузере, он возвращает точно правильный ожидаемый ответ.

Я попытался использовать эту проволочную акулу ... и я вижу фактические ожидаемые, полные данные возвращаются в выводе акулы, затем несколько строк, а затем красная линия, которая говорит: мы обнаружили, что это применимо (во многом это связано с конфигурациями служб 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 в моем браузере, он возвращает точно правильный ожидаемый ответ.

Я попытался использовать эту проволочную акулу ... и я вижу фактические ожидаемые, полные данные возвращаются в выводе акулы, затем несколько строк, а затем красная линия, которая говорит: мы обнаружили, что это применимо (во многом это связано с конфигурациями служб 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 в моем браузере, он возвращает точно правильный ожидаемый ответ.

Я попытался использовать эту проволочную акулу ... и я вижу фактические ожидаемые, полные данные возвращаются в выводе акулы, затем несколько строк, а затем красная линия, которая говорит: но так что ТАК разберутся правильно) все то, что я пробовал до сих пор, основано на том, что я нашел в Интернете. Никто из них не исправил это. Я проверил, что созданный URL-адрес правильный; если я вызываю точно такой же URL в моем браузере, он возвращает точно правильный ожидаемый ответ.

Я попытался использовать эту проволочную акулу ... и я вижу фактические ожидаемые, полные данные возвращаются в выводе акулы, затем несколько строк, а затем красная линия, которая говорит: но так что ТАК разберутся правильно) все то, что я пробовал до сих пор, основано на том, что я нашел в Интернете. Никто из них не исправил это. Я проверил, что созданный URL-адрес правильный; если я вызываю точно такой же URL в моем браузере, он возвращает точно правильный ожидаемый ответ.

Я попытался использовать эту проволочную акулу ... и я вижу фактические ожидаемые, полные данные возвращаются в выводе акулы, затем несколько строк, а затем красная линия, которая говорит: http> 51943 [RST] Seq = 1607 Win = 0 Len = 0 , которая является последней строкой, отображаемой перед тем, как .NET выдает ошибку.

Я также пытался включить System.Net трассировку / ведение журнала для каждого сообщения здесь на SO, и в выходном файле, из которого я вижу аналогичным образом, ожидаются все ожидаемые данные 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 для использования.

Две вещи, которые действительно меня заводят и смущают, это
а) он отлично работает при вызове в браузере
b) и трассировка WireShark, и .NET показывают все данные, которые на самом деле возвращаются , IS , и инфраструктура по какой-то причине исключает ПОСЛЕ получения всех данных!

Само по себе WebException используется очень мало, так как его InnerException является нулевым, а его Status просто говорит «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 () - также получает ту же ошибку закрытия соединения.

8
задан eidylon 18 August 2010 в 17:26
поделиться

2 ответа

Можете ли вы опубликовать все содержимое журнала трассировки на pastebin.com и разместить здесь ссылку?

Вы можете получить это исключение, потому что сервер может сказать в заголовке Content-Length, что он отправляет N байтов объекта, но на самом деле отправляет меньше N байтов и закрывает соединение.

Ответ:

Спасибо за данные. Из трассировки и трассировки wirehark кажется, что сервер не отправляет никаких заголовков ответов, а напрямую отправляет данные. Это нарушение протокола HTTP. Вот почему клиент выбрасывает исключение.

5
ответ дан 5 December 2019 в 15:16
поделиться

Вот как у меня это заработало ... Спасибо feroze за то, что указал мне в правильном направлении!
(начислены баллы)

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
3
ответ дан 5 December 2019 в 15:16
поделиться