【问题标题】:Persistent HttpURLConnection in JavaJava 中的持久 HttpURLConnection
【发布时间】:2011-03-19 06:07:18
【问题描述】:

我正在尝试编写一个 java 程序,它会自动下载并命名一些我最喜欢的网络漫画。由于我将从同一个域请求多个对象,因此我希望有一个持久的 http 连接,我可以保持打开状态,直到所有漫画都下载完毕。下面是我正在进行的工作。如何在不打开新的 http 连接的情况下从同一域但不同路径发出另一个请求?

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class ComicDownloader
{
    public static void main(String[] args)
    {
        URL url = null;
        HttpURLConnection httpc = null;
        BufferedReader input = null;

        try
        {
            url = new URL("http://www.cad-comic.com/cad/archive/2002");
            httpc = (HttpURLConnection) url.openConnection();
            input = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
            String inputLine;

            while ((inputLine = input.readLine()) != null)
            {
                System.out.println(inputLine);
            }

            input.close();
            httpc.disconnect();
        }
        catch (IOException ex)
        {
            System.out.println(ex);
        }
    }
}

【问题讨论】:

    标签: java httpurlconnection persistent


    【解决方案1】:

    即使 HttpURLConnection 默认启用 keep-alive,也不能保证 HttpURLConnection 对多个 HTTP 请求使用相同的 TCP 连接。在编写 HTTPS 客户端应用程序时,我遇到了同样的问题。通过使用 SSLContext、SSLSocketFactory 和 HttpsURLConnection 的单个实例解决了这个问题。

    public class MyHTTPClient {
        private SSLContext mSSLContext = null;
        private SSLSocketFactory mSSLSocketFactory = null;
        private HttpsURLConnection mConnection = null;
    
        public void init() {
            //Setup SSL context and Socket factory here
        }
    
        pubblic void sendRequest() {
            URL url = new URL("https://example.com/request_receiver");
            mConnection = (HttpsURLConnection) url.openConnection();
            mConnection.setSSLSocketFactory(mSSLSocketFactory);
    
            // Setup request property and send request
            // Open input stream to read response
            // Close output, input streams
            
            mConnection.disconnect();
        }
    }
    

    【讨论】:

      【解决方案2】:

      根据这个链接http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html,HTTP连接重用默认是开启的,你可以使用Wireshark来检查你的客户端和服务器之间的交互。第一个请求包含 TCP 和 SSL 握手(如果您的请求是 https),后续请求在 keep-alive 时间内触发,不包含 TCP 和 SSL 握手,只是应用程序数据传输。

      【讨论】:

        【解决方案3】:

        根据documentation here,HTTP 持久性在 Java 中被透明地处理,尽管它为您提供了通过http.keepAlivehttp.maxConnections 系统属性控制它的选项。

        然而,

        当前的实现没有 缓冲响应体。意思是 该应用程序必须完成 阅读响应正文或调用 close() 放弃其余的 响应体,为了 要重用的连接。此外, 当前的实现不会尝试 清理时的块读取 连接,意思是如果整个 响应正文不可用,则 连接不会被重用。

        看看这个链接,看看它是否真的对你有帮助。

        【讨论】:

        • 链接已失效?它还适用于较新版本的 java 吗?
        • @royerdpack 当然可以。你不能真的相信他们会把这样一个有价值的功能拿出来。
        • @rogerdpack 下次使用这样的 Google 搜索:google.com/search?q=java+api+doc+net%2Fhttp-keepalive.html 同时正在修复链接。
        • 完成阅读并且不要在输入流或输出流上调用close()。调用 close() 导致我的客户端代码重新打开 HTTPS 连接。
        • FWIW 我想我读过一次 stackoverflow.com/a/4767595/32453 调用断开连接(就像 OP 一样)也会导致 Socket 不能被重用/缓存......
        猜你喜欢
        • 1970-01-01
        • 2015-12-09
        • 1970-01-01
        • 2020-09-22
        • 1970-01-01
        • 1970-01-01
        • 2011-12-11
        • 1970-01-01
        相关资源
        最近更新 更多