【问题标题】:Opening url.openstream throws invalid http response打开 url.openstream 会引发无效的 http 响应
【发布时间】:2016-05-04 17:00:45
【问题描述】:

我正在尝试从温度模块读取文件,当我在 url 上调用 openStream() 时,我收到一个带有“无效 Http 响应”消息的 IOExeption

SEVERE: null
java.io.IOException: Invalid Http response
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1555)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at java.net.URL.openStream(URL.java:1038)
at thermometerpoller.Poller.poll(Poller.java:38)

我可以远程登录到温度模块:

telnet 192.168.142.55 80
Trying 192.168.142.55...
Connected to 192.168.142.55.
Escape character is '^]'.
GET /state.xml HTTP/1.1

<?xml version='1.0' encoding='utf-8'?>
<datavalues>
<units>F</units>
<sensor1temp>74.0</sensor1temp>
<sensor2temp>67.0</sensor2temp>
<sensor3temp>xx.x</sensor3temp>
<sensor4temp>xx.x</sensor4temp>
<relay1state>0</relay1state>
<relay2state>0</relay2state>
</datavalues>

Connection closed by foreign host.

温度模块似乎没有在回复中发送任何标题。 不幸的是,当我查看HttpURLConnection.java 时,如果没有响应代码,它会抛出 IOException。

我的问题是,有没有办法在不关心响应代码的情况下通过库或其他方法获取文件内容?

【问题讨论】:

  • 如果您在本地系统上使用防火墙,请将其禁用并进行测试。我遇到了类似的问题,后来我在防火墙日志中看到,它阻止了从我的 java 程序发送的请求。

标签: java http url


【解决方案1】:

由于服务器是not HTTP compliant,因此您不应使用 URL 或 URLConnection。改用普通的 Socket:

Document doc;

final Socket connection = new Socket("192.168.142.55", 80);

try (final OutputStream out = connection.getOutputStream();
     InputStream in = connection.getInputStream()) {

    Callable<Void> requestSender = new Callable<Void>() {
        @Override
        public Void call()
        throws IOException {
            String request = "GET /state.xml HTTP/1.1\n\n";
            out.write(request.getBytes(StandardCharsets.US_ASCII));
            return null;
        }
    };
    ExecutorService background = Executors.newSingleThreadExecutor();
    Future<?> request = background.submit(requestSender);

    doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);

    request.get();
    background.shutdown();
}

【讨论】:

  • 这段代码在发送请求后关闭了socket,那么它怎么能收到响应呢?注意 HTTP 中的行终止符是\r\n,而不仅仅是\n
  • @EJP 你说得对。更新。至于换行符,我只是在附和 nelsonslament 在他的原始 telnet 连接中显然输入的内容;服务器似乎没有遵循与真正的 HTTP 服务器相同的规则。
  • FWIW 兼容的 telnet 客户端将行尾作为 CR LF 发送(请参阅 RFC 854),并且并非巧合 RFC 指定 HTTP 标头和类似 SMTP 之类的相同行尾和 FTP 命令。如果没有更精确的测试,这个服务器/设备是否关心 CRLF 和 LF 或者其他东西是未知的。
猜你喜欢
  • 2012-12-29
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 2021-09-12
相关资源
最近更新 更多