简述
对于Android开发来说,HTTP是网络开发中最为重要的、使用频率最高的手段,也是面试常问到的面试题。因此,深入了解HTTP是必备技能,只有了解它的基本原理才能够更好的运用。
HTTP网络请求原理
HTTP是一种应用层协议,它通过TCP实现了可靠的数据传输,能够保证数据的完整性、正确性。对于移动开发而言,网络应用基本上都是C/S架构。客户端通过向服务器发起特定的请求,服务器返回结果,客户端解析结果,再将结果展现在UI上。详细交互的流程分为如下几步:
- 客户端执行网络请求,从URL中解析出服务器的主机名;
- 将服务器的主机名转换成服务器的IP地址;
- 将端口号从URL中解析出来;
- 建立一条客户端与Web服务器的TCP连接;
- 客户端通过输出流向服务器发送一条HTTP请求;
- 服务器向客户端回送一条HTTP响应报文;
- 客户端从输入流获取报文;
- 客户端解析报文,关闭连接;
- 客户端将结果显示在UI上。
有人可能对上面流程有所疑惑,在开发过程用到的网络框架中从来都只要请求方式(post、get、put、delete等)和传递URL、参数,没有上述流程中的1、2、3步,而且IP+端口号是SOCKET通信俩大必备要素;如果你有如此疑惑,你就该仔细的看看这篇文章,首先给你解惑,我们的后台服务一般不会直接暴露IP和端口号,而是申请域名(如:www.baidu.com),所以我们传递URL首先进入域名服务器,在域名服务器中为我们进行了1-3步操作;HTTP确实是socket实现的。
模拟HTTP过程
在模拟http交互的过程前我们需要了解HTTP报文格式。不同的请求方式,它们的请求格式可能是不一样的,请求格式就是所谓的报文格式。但是通常来说一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成的,如下图:
客户端(post请求)
//这里不展示域名解析,IP和PORT都为解析后的
public class Client {
//URL通过域名解析后的IP
public String ip;
//URL通过域名解析后的PORT,即服务器的端口
public int port;
//请求参数
private Map<String,String>mParamsMap = new HashMap<>();
//客户端Socket
Socket mSocket;
public Client(String ip,int port){
this.port = port;
this.ip = ip;
}
public void addParam(String key,String value){
mParamsMap.put(key, value);
}
public void execute(){
try{
//创建Socket连接
mSocket = new Socket(ip,port);
PrintStream outputStream = new PrintStream(mSocket.getOutputStream());
BufferedReader inputStream = new BufferedReader(new InputStreamReader(
mSocket.getInputStream()
));
final String boundary = "my_boundary_123";//用来设置请求边界
//写入header
writeHeader(boundary,outputStream);
//写入参数
writeParams(boundary,outputStream);
//等待返回数据
waitResponse(inputStream);
}catch (UnknownHostException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if (mSocket!=null){
mSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//代码省略
}