Domanda

Ho un'applicazione scritta in VB.NET ( non asp.net, si tratta di una console app di Windows). Sto cercando di chiamare un URL (una pagina HTML) e tornare la risposta in una stringa. La risposta è diritta JSON, nessun tag HTML di sorta. Si apre con { e si chiude con }.

I creare il bene oggetto HttpWebRequest. Quindi chiamare req.GetResponse(). Non appena lo faccio ottengo l'errore di The underlying connection was closed: The connection was closed unexpectedly. Sono stato googling e controllo StackOverflow, e tutto provato ho trovato che si applica (un sacco di esso ha a che fare con le configurazioni di servizio WCF, che non si applicano).

Ecco il mio codice:

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

Le linee commentate (commento stile sbagliato, ma così si analizza bene) sono tutte le cose che ho provato finora basato su quello che ho trovato in rete. Nessuno di loro è stato risolto. Ho verificato che l'essere costruito URL è corretto; se chiamo l'esatto stesso URL nel browser restituisce esattamente la giusta attesa di risposta.

Ho provato wiresharking ... e vedo il attesi, dati effettivi completi tornano nell'output squalo, e poi un paio di righe, e poi una linea rossa che dice: http > 51943 [RST] Seq=1607 Win=0 Len=0 che è l'ultima linea di presentarsi prima di .NET sta gettando l'errore.

Ho provato anche accendere System.Net tracing / registrazione per un post qui su SO, e nel file di output da quel che vedo allo stesso modo tutti i dati JSON attesi Il tornare, ma dopo si ritorna getta queste righe nel registro di traccia 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.

Tutte le idee dove andare per cercare di capire questo fuori? Stiamo leggendo questi dati di alcuni dispositivi sensori ambientali di monitoraggio, e ci hanno dato questa URL da utilizzare.

Due cose che mi ha veramente ottenere e mi confondono su questo sono che
a) che funziona perfettamente bene quando viene chiamato in un browser
b) sia WireShark e .NET tracing mostra tutti i dati effettivamente è tornando, e il quadro è per qualche motivo eccetto dopo la ricezione di tutti i dati!

Il WebException in sé è di essere molto poco, come il suo InnerException è nullo e il suo status dice solo "ConnectionClosed {8}"

Grazie in anticipo !!!

UPDATE 08/18 1130: Inoltre ho provato ora utilizzando solo System.Net.WebRequest al contrario di HttpWebRequest. Questo non ha fatto alcuna differenza neanche.

UPDATE 08/18 1222: Ho appena provato il passaggio mio codice invece di utilizzare [Http]Web[Request|Response] ad oscuramento di un oggetto WebClient, invece, e utilizzando il suo metodo DownloadString(). Questo però anche getta lo stesso errore esatto.

UPDATE 08/18 1230:. Provato using My.Computer.Network.DownloadFile() - ottiene anche l'errore di chiusura stessa connessione

È stato utile?

Soluzione

Puoi pubblicare l'intero contenuto del registro di traccia su pastebin.com e postare un link qui?

Si potrebbe essere sempre questa eccezione perché il server potrebbe dire in "Content-Length" intestazione che è l'invio di n byte di entità, ma in realtà è l'invio di meno di N byte e chiudere la connessione.

Risposta:

Grazie per i dati. Dal TraceLog e traccia Wireshark, sembra che il server non sta inviando tutte le intestazioni di risposta, e l'invio direttamente i dati. Si tratta di una violazione del protocollo HTTP. È per questo che il cliente sta gettando l'eccezione.

Altri suggerimenti

Ecco come ho ottenuto che funziona ... Grazie a Feroze per avermi nella giusta direzione!
(Punti assegnati)

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

Questo mi aiuta. Spero che aiuta qualcuno pure.

Subito dopo aver creato HttpWebRequest oggetto, aggiungere questa riga.

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;

Che cosa significa è specifica il Secure Socket Layer (SSL) 3.0 come protocollo di sicurezza

http://support.microsoft.com/kb/915599

Controlla la latenza della richiesta. Se si tratta di più di un paio ms allora vale la pena disabilitando l'algoritmo Nagle

 ServicePointManager.UseNagleAlgorithm = false;

ho avuto lo stesso problema per quanto riguarda la richiesta senza un corpo. Nel mio caso, l'impostazione del ContentLength a ZERO risolto il problema.

Nel mio caso il problema è stato che abbiamo usato "http: // .." come indirizzo di servizio invece di "https: //" ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top