0、在认识HTTP前先认识URL
在我们认识HTTP之前,有必要先弄清楚URL的组成,例如:
http://www.******.com/china/index.htm
它的含义如下:
1. http://:代表超文本转移协议,通知****.com服务器显示Web页,通常不用输入;
2. www:代表一个Web(万维网)服务器;
3.****.com/:这是装有网页的服务器的域名,或站点服务器的名称;
4.China/:为该服务器上的子目录,就好像我们的文件夹;
5.Index.htm:index.htm是文件夹中的一个HTML文件(网页)。
1、什么是HTTP
HTTP协议是一种应用层协议,HTTP是HyperTextTransfer Protocol(超文本传输协议)的英文缩写。HTTP可以通过传输层的TCP协议在客户端和服务器之间传输数据。HTTP协议主要用于Web浏览器和Web服务器之间的数据交换。我们在使用IE或Firefox浏览网页或下载Web资源时,通过在地址栏中输入,开头的4个字母http就相当于通知浏览器使用HTTP协议来和host所确定的服务器进行通讯。
HTTP/1.0
这是第一个在通讯中指定版本号的 HTTP协议版本,至今仍被广泛采用,特别是在代理服务器中。
HTTP/1.1
当前版本。持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求,以便降低线路负载,提高传输速度。
2、HTTP工作方式
HTTP协议采用了请求/响应的工作方式。基于HTTP1.0协议的客户端在每次向服务器发出请求后,服务器就会向客户端返回响应消息(包括请求是否正确以及所请求的数据),在确认客户端已经收到响应消息后,服务端就会关闭网络连接(其实是关闭TCP连接)。在这个数据传输过程中,并不保存任何历史信息和状态信息,因此,HTTP协议也被认为是无状态的协议,图1描绘了HTTP1.0协议的通讯过程。
3、HTTP响应码
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求
4、HTTP的请求体与回复体
5、两种HTTP通信
(1)HttpURLConnection
(2)HttpClientURLConnection
下面举例说明第一种HttpURLConnection
private class DownThread extends Thread { // 当前线程的下载位置 private int startPos; // 定义当前线程负责下载的文件大小 private int currentPartSize; // 当前线程需要下载的文件块 private RandomAccessFile currentPart; // 定义已经该线程已下载的字节数 public int length; public DownThread(int startPos, int currentPartSize, RandomAccessFile currentPart) { this.startPos = startPos; this.currentPartSize = currentPartSize; this.currentPart = currentPart; } @Override public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection)url .openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); conn.setRequestProperty( "Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " + "application/x-shockwave-flash, application/xaml+xml, " + "application/vnd.ms-xpsdocument, application/x-ms-xbap, " + "application/x-ms-application, application/vnd.ms-excel, " + "application/vnd.ms-powerpoint, application/msword, */*"); conn.setRequestProperty("Accept-Language", "zh-CN"); conn.setRequestProperty("Charset", "UTF-8"); InputStream inStream = conn.getInputStream(); // 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。 inStream.skip(this.startPos); byte[] buffer = new byte[1024]; int hasRead = 0; // 读取网络数据,并写入本地文件 while (length < currentPartSize && (hasRead = inStream.read(buffer)) > 0) { currentPart.write(buffer, 0, hasRead); // 累计该线程下载的总大小 length += hasRead; } currentPart.close(); inStream.close(); } catch (Exception e) { e.printStackTrace(); } } }