从vb.net中的硬件设备读取远程XML文件(协议违规)

时间:2015-03-18 21:43:17

标签: vb.net http

我有一个内置了小型Web服务器的硬件设备。我无法控制Web服务器的工作方式或编程方式。它在您请求时发送回一个小的XML文件,问题是服务器不发回任何头信息。

以下是我尝试连接它的方法。 (我甚至将设备放在自己的静态IP上供您测试 - 包含在下面的代码片段中)。

Dim request As HttpWebRequest = HttpWebRequest.Create("http://96.39.92.3:81/state.xml")
request.Method = WebRequestMethods.Http.Get
' I Have added the following two lines to test, they do not help alone or together.
' I also added:   <httpWebRequest useUnsafeHeaderParsing="true" /> to the config file.
request.ProtocolVersion = HttpVersion.Version10
request.ServicePoint.Expect100Continue = False
Dim oResponse As HttpWebResponse = request.GetResponse()
Dim reader As New StreamReader(oResponse.GetResponseStream())
Dim tmp As String = reader.ReadToEnd()
oResponse.Close()
If oResponse.StatusCode = "200" Then
     MsgBox(tmp)
Else
     Throw New ApplicationException("Error Occurred, Code: " & oResponse.StatusCode)
End If    

我也尝试过使用具有相同结果的XmlTextReader。

感谢您的帮助。

编辑:提琴响应(使用Chrome来请求文档)

RAW REQUEST:
GET http://96.39.92.3:81/state.xml HTTP/1.1
Host: 96.39.92.3:81
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8


RAW RESPONSE:
HTTP/1.0 200 This buggy server did not return headers

<?xml version="1.0" encoding="utf-8"?>
<datavalues>
<relaystate>1</relaystate>
<inputstate>0</inputstate>
<rebootstate>0</rebootstate>
<totalreboots>0</totalreboots>
</datavalues>

随着Fiddler的开放,上面的httpwebrequest正常运作。 Fiddler必须在它到达.net应用程序之前重新添加标题。

编辑2:请求的调整后的标头值。这使得icepickles tcpclient为我工作。 cookie值是必需的。

WriteTextToStream(stream, tcpClient, "GET /state.xml?relayState=1 HTTP/1.0" & ControlChars.CrLf & _
" Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*" & ControlChars.CrLf & _
"Referer: " & ControlChars.CrLf & "Accept -Language : en -gb" & ControlChars.CrLf & _
"Content-Type: application/x-www-form-urlencoded" & ControlChars.CrLf & _
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6" & ControlChars.CrLf & _
"Host: 192.168.1.232" & ControlChars.CrLf & _
"Connection: Keep -Alive" & ControlChars.CrLf & ControlChars.CrLf & _
"Cookie:")

1 个答案:

答案 0 :(得分:1)

我根据评论重新启动了这篇文章,原始回复应该仍然在编辑链中,以防有人需要/想要它。

我的想法是,不是使用内置所有额外检查的HttpWebRequest,而是使用TcpClient连接您的服务器,或者因为您的额外问题,尝试使用基本Socket连接服务器,并请求您的数据是手动的(并且忽略了您不会获得标题的事实,只是响应中的文件)

以下内容可以从我的计算机上请求url,我确定它也适用于以前的TcpClient(请参阅编辑),但在这种情况下,我只使用了System.Net.Sockets.Socket代替。

以前版本中的错误实际上是我在字符串文字中使用C#\ r \ n而不是VB.net VbCrLf,我的错误;)

Imports System.Net.Sockets
Imports System.Net
Imports System.Text

Module Module1
    Sub WriteTextToStream(ByRef stream As NetworkStream, text As String)
        Dim buffer As Byte() = System.Text.Encoding.ASCII.GetBytes(text)
        stream.Write(buffer, 0, buffer.Length)
    End Sub

    Function CreateHeaders(ParamArray headers() As KeyValuePair(Of String, String)) As String
        Dim message As New StringBuilder()
        If headers IsNot Nothing Then
            For Each kvp In headers
                message.AppendLine(kvp.Key & ": " & kvp.Value)
            Next
        End If
        Return message.ToString()
    End Function

    Function DownloadSocketClient(server As String, port As Integer, path As String, host As String) As String
        Dim hostEntry = Dns.GetHostEntry(server)
        Dim ipEndPoint As New IPEndPoint(hostEntry.AddressList(0), port)
        Dim textResponse As String = String.Empty

        Using tcpClient As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

            tcpClient.Connect(ipEndPoint)

            Dim networkHost As String = host & ":" & port
            Dim headerMessage As String = CreateHeaders(
                New KeyValuePair(Of String, String)("Host", networkHost)
            )

            ' autoconnect
            Using stream As NetworkStream = New NetworkStream(tcpClient)
                ' send request to server
                WriteTextToStream(stream, String.Format("GET /{1} HTTP/1.1{3}{2}{3}", networkHost, path, headerMessage, Environment.NewLine))

                'wait till data is available
                While Not stream.DataAvailable
                    System.Threading.Thread.Sleep(1)
                End While

                ' get the response from the networkstream
                Dim requestSize As Integer = tcpClient.ReceiveBufferSize
                Dim result As Integer
                Dim readRequest(requestSize) As Byte
                While stream.DataAvailable
                    result = stream.Read(readRequest, 0, requestSize)
                    textResponse &= System.Text.Encoding.UTF8.GetString(readRequest, 0, result)
                End While
            End Using
        End Using
        Return textResponse
    End Function

    Sub Main()
        Dim fileContent As String = DownloadSocketClient("stackoverflow.server.textconnects.com", 81, "state.xml", "stackoverflow.server.textconnects.com")
        Console.WriteLine("Received file: " & vbCrLf & fileContent)
        Console.ReadLine()
    End Sub

End Module