利用管道化连接下载网页 Java
来源:互联网 发布:java maven 项目打包 编辑:程序博客网 时间:2024/06/07 05:38
HTTP连接的建立需要时间。如果我们要从一台服务器上获取4个文件,获取每个文件都要重新建立连接来获取数据,这势必会降低文件下载效率,因为有一部分时间花费在建立连接上了,而不是真正在传输有用数据,如图a所示:
如果我们能建立一个连接,传输完所有四个文件,再关闭连接,必然会增加文件下载效率,因为节省了多次建立连接的开销,持久连接就是这样的连接,它的工作方式如图b所示:
简单的持久连接有个问题,就是每次都要等到我们获得了上一次请求的响应之后,才能发起下一次连接,这导致请求的时候,输入流是完全闲置的,获取响应的时候,输出流是完全闲置的。如果我们能一边发送请求,一边接收响应,这必然能更加充分的利用这个连接,可以被这样使用的持久连接叫做管道化连接,它的工作方式如图c所示:
下面给出的Java代码是通过一个管道化连接从服务器上获取多个文件的示例:
package socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.StandardOpenOption;public class ReuseSocket { public static void main(String[] args) throws UnknownHostException, IOException { String host = "www.cnblogs.com"; int port = 80; String path = "/chenying99/p/3735282.html"; String path2 = "/everSeeker/p/5462853.html"; String result = getByPipePipelinedConnection(host, port, path, path2); writeFile(result, "d:/test/pipelined.html", "utf-8"); } /** * 通过一个管道化连接获取host指定的主机上paths指定的所有文件 * @param host 主机名 * @param port 端口 * @param paths host指定的主机上的文件路径集合 * @return 服务器返回的结果 * @throws UnknownHostException * @throws IOException */ public static String getByPipePipelinedConnection(String host, int port, String...paths) throws UnknownHostException, IOException { StringBuilder lines = new StringBuilder(); try(Socket socket = new Socket(host, port); // 输出流 PrintWriter printWriter = new PrintWriter((new OutputStreamWriter( socket.getOutputStream(), "utf-8"))); // 输入流 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( socket.getInputStream(), "utf-8")); ) { for (String path : paths) { String requestHead = generateRequestHead(host, path); printWriter.println(requestHead); printWriter.flush(); } String line = null; while ((line = bufferedReader.readLine()) != null) { lines.append(line); lines.append(System.lineSeparator()); } } return lines.toString(); } /** * * @param host 主机名 * @param path 主机上某个文件的路径 * @return 获得host指定主机上的path指定的文件的请求头 */ private static String generateRequestHead(String host, String path) { StringBuffer requestHeader = new StringBuffer(); requestHeader .append("GET " + path + " HTTP/1.1\n") .append("Accept: text/html, application/xhtml+xml, */*\n") .append("Accept-Language:zh-CN,zh;q=0.8\n") .append("User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)\n") .append("HOST:" + host + "\n") .append("\n"); return requestHeader.toString(); } /** * 把字符串写进文件,文件已经存在会覆盖原文件 * @param content 字符串 * @param pathName 文件路径名 * @param charsetName 字符集 */ private static void writeFile(String content, String pathName, String charsetName) { Path path = Paths.get(pathName); try { Files.write(path, content.getBytes(charsetName), StandardOpenOption.CREATE); } catch (IOException e) { e.printStackTrace(); } }}
想更细致的了解管道化连接,可以阅读《HTTP权威指南》4.6节,本文的图也来自这本书。
0 0
- 利用管道化连接下载网页 Java
- 4.6 管道化连接
- java下载网页
- java 程序下载网页
- java 下载网页,图片
- 用java下载网页
- Java PhantomJs下载网页
- Java下载网页文件
- java连接网页
- 利用线程池多线程下载网页信息
- 利用python下载网页到本地(python3)
- 利用python下载网页上的文件
- 利用java.net包访问网络,连接网页并返回html页面代码
- 利用java连接mysql
- 利用Java抓取网页数据
- 利用java获取网页内容
- java:使用URL下载网页
- java多线程网页下载代码
- Fedora 13 系统安装
- 破门锁
- http-客户端识别与cookie机制
- Services的生命周期
- Linux常用操作
- 利用管道化连接下载网页 Java
- Swift 基本语法 : 一
- leetcode 183. Customers Who Never Order
- hdu4859 海岸线
- 第10周项目3-警察与厨师(2)
- mysql保存文件
- 图像特效---(Instagram)1977滤镜
- 使用github搭建博客
- [Spark优化]在Spark中使用Kryo序列化