Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在响应完成之前关闭HttpURLConnection 背景_Java_Httpurlconnection - Fatal编程技术网

Java 在响应完成之前关闭HttpURLConnection 背景

Java 在响应完成之前关闭HttpURLConnection 背景,java,httpurlconnection,Java,Httpurlconnection,我在客户端使用HTTP流(服务器推送)情况下的响应。虽然服务器可以通过关闭响应来关闭连接,但客户机也需要能够做到这一点 问题 客户端在单独的线程中处理InputStream,如下所示: @Override public void run() { try { for (int b = in.read(); b >= 0; b = in.read()) { char c = (char) b; // Do somethin

我在客户端使用HTTP流(服务器推送)情况下的响应。虽然服务器可以通过关闭响应来关闭连接,但客户机也需要能够做到这一点

问题 客户端在单独的线程中处理
InputStream
,如下所示:

@Override
public void run() {
    try {
        for (int b = in.read(); b >= 0; b = in.read()) {
            char c = (char) b;
            // Do something with the character
            // ...
        }
    }
    catch (IOException e) {
    }
}
因此,当我从启动连接的线程调用时(重要的信息是它与处理输入的线程不同),该调用将无限期挂起。我甚至留了一夜,它仍然挂着。甚至打电话也没用


建议?

如果服务器未关闭连接但停止发送数据,则.read()中的
将被阻止。现在,请注意
HttpURLConnection.HttpInputStream.close()
的代码也将尝试从流中读取,以确定到达流的末尾(。 依次从
disconnect()
调用
close()
。最后,线程被阻塞

因此,您似乎需要更改逻辑。我假设您根据某些条件关闭连接。因此,在读取线程中的下一个字节之前,不要在不同的线程中检查条件,然后断开连接


顺便说一下,
Thread.interrupt()
对您没有帮助,因为它只会在您等待IO时中断正在监视器上等待的线程。

看起来,如果不更改读取线程以使用轮询并在没有可用字节时短暂休眠,则无法完成此操作,同时检查一些标志以查看线程是否应该结束

解决方案是只使用ApacheHTTP组件,通过将GET请求的代码封装在一个类中,可以很容易地集成到现有代码中

public class HttpGetConnection implements AutoCloseable {
    public HttpGetConnection(String url) throws IOException {
        client = new DefaultHttpClient();
        get = new HttpGet(url);
        response = client.execute(get);
        entity = response.getEntity();
    }

    public InputStream getContent() throws IOException {
        content = entity.getContent();
        return content;
    }

    @Override
    public void close() throws Exception {
        get.abort();
        try {
            content.close();
        }
        catch (IOException e) {
        }
    }

    private HttpClient client;
    private HttpGet get;
    private HttpResponse response;
    private HttpEntity entity;
    private InputStream content;
}

原始post中的循环可以保持原样,读取线程将在调用
HttpGetConnection.close()
后不久死亡。另一种解决方法是将输入流包装到通道中并使用该通道(
Channels.newChannel
),正如解决方案中所建议的那样。这将导致线程中断时关闭底层输入流。但是,JDK中有一条评论说,它实际上不可中断。在我的测试中,它似乎可以工作。我要求提供更多信息。

谢谢。唯一的问题是,在大多数情况下,读取线程被阻塞,so它没有机会检查条件。
InputStream
上没有允许超时的读取方法。您可以使用
available()
查看流中是否有任何内容。如果没有,您可以暂停并在暂停后重新检查您的状态,这样您就不会阻塞空流。请查看我的答案-已经承认这一事实,并且它需要一个不太理想的轮询/睡眠/检查周期。无论如何,谢谢。@AlexGitelman找不到源代码。您介意吗更新你的链接?如果是这样的话,我认为没有人应该在不使用可用方法的情况下编写这样的代码。