背景
OkHttp框架是基于Socket实现的,那么是怎么做到的呢?
1、Socket发起Http/Https Get请求
Http属于网络模型中的应用层,Socket属于传输层。Http请求是可以用Socket来实现的,只要Socket发出的请求格式按照Http协议规范,便是一个Http请求。那么Http请求的协议规范是什么样的呢?
1.1 Get请求报文格式
例如:
https://www.baidu.com?client=1
转换成一个Http请求报文如下:
GET /?client=1 HTTP/1.1
Host: www.baidu.com
1.2、Java代码实现Get请求
public static void main(String[] args) {
try {
//Https请求用SSLSocketFactory,如果是Http使用Socket
Socket socket = SSLSocketFactory.getDefault().createSocket("www.baidu.com", 443);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//注意\r\n代表换行
bw.write("GET /?client=1 HTTP/1.1\r\n");
//这里第二个\r\n代表空行,空行是http协议里要求的,不能省略
bw.write("Host: www.baidu.com\r\n\r\n");
bw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {
String readLine = null;
if ((readLine = br.readLine()) != null) {
System.out.println(readLine);
} else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
1.3、Get请求带请求头
实际业务中,接口通常会带有token作为校验用户身份需要,那么这个请求头是怎么处理的呢?
GET /?client=1 HTTP/1.1
//请求属性集,写socket内容是写上token: 123456\r\n即可携带上
token: 123456
Host: www.baidu.com
1.4、小结
从上面的案例可以知道,用Socket发Http请求,只要在Socket输出流中写入满足Http协议规范的内容即可。
2、Socket发起Http/Https Post请求
2.1、案例:post请求
对应的报文如下:
POST /?client=1 HTTP/1.1
token: 123456
Content-Length: 7
Content-Type: application/json
Host: www.baidu.com
{"a":1}
和get请求的区别:post请求有两个多的固定字段,Content-Length和Content-Type,分别对应请求体的长度和类型,同时在Host字段后空行携带上请求体,而Get请求是不允许有请求体的
2.2、Java代码实现Post请求
private static void httpPost() {
try {
//Https请求用SSLSocketFactory,如果是Http使用Socket
Socket socket = SSLSocketFactory.getDefault().createSocket("www.baidu.com", 443);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write("POST /?client=1 HTTP/1.1\r\n");
bw.write("token: 123456\r\n");
bw.write("Content-Length: 3\r\n");
bw.write("Content-Type: application/json\r\n");
bw.write("Host: www.baidu.com\r\n\r\n");
bw.write("{\"a\":1}\r\n");
bw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {
String readLine = null;
if ((readLine = br.readLine()) != null) {
System.out.println(readLine);
} else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
2、Http报文格式
2.1、Http请求报文格式
2.2、Http响应报文格式
2.3、小结
使用Socket实现Http Get和Post请求,只要按照Http协议规范,在Socket OutPutStream中写入符合要求的内容即可,而解析响应和发起请求同理,按照格式解析即可获得响应内容