记一次使用Socket模拟HTTP请求
2021-04-09 08:25
标签:windows 代码 input nts rgs 新建 sys nec 图片 直接进入主题。 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议,HTTP是基于TCP/IP通信协议来传递数据。 Java中的正好有一个类可以实现TCP的传输与接收,那就是Socket。 首先要先起一个SpringBoot项目用于接收HTTP请求,Controller很简单,接收请求,并返回请求的内容 在发送报文前先了解一下HTTP协议的报文结构。 一个完整的GET请求的请求报文是这样的: (来源Chrome) 接下来就是使用Socket来发送这样结构的报文,模拟一次HTTP请求。 将上面的代码运行后得到 会发现一个问题,请求实体b=2&c=3是一起发送过去的,但是后端解析的时候没能解析出来,因为GET请求是不包含请求实体的。 把GET换成POST后就得到 后端能够正确的获取到了请求实体。 在服务端返回的数据,结构跟请求报文差不多。第一行是状态行,第一行后的 这三行是消息的报头,表示了内容的类型,内容的长度跟服务器的响应时间。 消息报头后有一行空行,然后就是响应的内容了,也就是服务端返回的数据。 记一次使用Socket模拟HTTP请求 标签:windows 代码 input nts rgs 新建 sys nec 图片 原文地址:https://www.cnblogs.com/jellybean961/p/12448027.html@RequestMapping("response")
@Controller
public class MainController {
private static Logger LOG = LoggerFactory.getLogger(MainController .class);
@RequestMapping("index.html")
@ResponseBody
public String index(HttpServletRequest request){
LOG.info("请求内容:"+requestContent(request));
return "请求内容:"+requestContent(request);
}
public String requestContent(HttpServletRequest request){
Map
GET /response/index.html HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Sec-Fetch-Dest: document
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9 public static void main(String[] args) {
try {
// 新建一个socket套接字,地址跟端口都指向springboot项目
Socket socket = new Socket("127.0.0.1", 8080);
// 拼接http请求报文
StringBuilder sb = new StringBuilder();
// 拼接请求行
sb.append("GET http://127.0.0.1:8080/response/index.html?a=1 HTTP/1.1\r\n");
// 开始拼接请求头
sb.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n");
sb.append("Connection: keep-alive\r\n");
// Content-Length 跟 Content-Type 在POST请求时起很重要的作用,没有这两个请求头,就算你发送的请求实体,服务端也是解析不到请求实体的。
sb.append("Content-Length: 7\r\n");
sb.append("Content-Type: application/x-www-form-urlencoded\r\n");
sb.append("Host: 127.0.0.1:8080\r\n");
sb.append("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36\r\n");
// 结束拼接请求头,然后拼接一个空行
sb.append("\r\n");
// 这里是请求实体,用于POST测试
sb.append("b=2&c=3");
// 将拼接好的报文发送至服务端
socket.getOutputStream().write(sb.toString().getBytes());
System.out.println("发送数据");
System.out.println(sb.toString());
// 开启一个线程去接收服务端返回的数据
// 开线程的目的是服务端需要时间进行响应,所以直接获取inputstream是拿不到服务端返回的数据的,因为服务端还没返回,你就直接去获取,这样是拿不到的
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
byte[] b = new byte[1024];
int off = 0;try {
while(socket.getInputStream().read(b, off, b.length) != -1) {
System.out.println("返回数据:"+new String(b,"UTF-8"));
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}).start();
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
}
发送数据
GET http://127.0.0.1:8080/response/index.html?a=1 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
b=2&c=3
返回数据:HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Content-Length: 16
Date: Mon, 09 Mar 2020 04:13:41 GMT
请求内容:a=1
发送数据
POST http://127.0.0.1:8080/response/index.html?a=1 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
b=2&c=3
返回数据:HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Content-Length: 24
Date: Mon, 09 Mar 2020 04:17:21 GMT
请求内容:a=1&b=2&c=3
Content-Type: text/html;charset=UTF-8
Content-Length: 24
Date: Mon, 09 Mar 2020 04:17:21 GMT
文章标题:记一次使用Socket模拟HTTP请求
文章链接:http://soscw.com/index.php/essay/73247.html