07-HTTP协议
扩展:TCP和UDP的区别
TCP(传输控制协议):是一种面向连接的、可靠的、基于字节流的传输层通信协议,是专门为了在不可靠的网络中提供一个可靠的端对端字节流而设计的,面向字节流。
UDP(用户数据报协议):是iso参考模型中一种无连接的传输层协议,提供简单不可靠的非连接传输层服务,面向报文
- TCP是面向连接的,可靠性高;UDP是基于非连接的,可靠性低
- 由于TCP是连接的通信,需要有三次握手、重新确认等连接过程,会有延时,实时性差,同时过程复杂,也使其易于攻击;UDP没有建立连接的过程,因而实时性较强,也稍安全
- 在传输相同大小的数据时,TCP首部开销20字节;UDP首部开销8字节,TCP报头比UDP复杂,故实际包含的用户数据较少。
- TCP在IP协议的基础上添加了序号机制、确认机制、超时重传机制等,保证了传输的可靠性,不会出现丢包或乱序,而UDP有丢包,故TCP开销大,UDP开销较小
- 每条TCP连接只能时点到点的;UDP支持一对一、一对多、多对一、多对多的交互通信
例如,之前做的hello接口案例,可以看到以下的请求数据和相应数据
GET请求 和 POST请求的区别:
1)get请求
2)post请求
常见的 HTTP 状态码:
状态码文档:状态 | Status - HTTP 中文开发手册 - 开发者手册 - 腾讯云开发者社区-腾讯云 (tencent.com)
案例:使用代码实现HTTP协议解析
a.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1" cellspacing="0" width="500"> <tr align="center"> <th>序号</th> <th>品牌名称</th> <th>企业名称</th> </tr> <tr align="center"> <td>010</td> <td>华为</td> <td>华为技术有限公司</td> </tr> <tr align="center"> <td>009</td> <td>三只松鼠</td> <td>三只松鼠</td> </tr> <tr align="center"> <td>008</td> <td>小米</td> <td>小米科技有限公司</td> </tr> </table> </body> </html>
Server.java文件
package com.itheima.controller; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.logging.Handler; /* * 自定义web服务器 * */ public class Server { public static void main(String[] args) throws IOException { // 创建ServerSocket对象, 监听8080端口 ServerSocket serverSocket = new ServerSocket(8080); System.out.println("服务器启动成功, 监听端口: 8080"); // 服务器启动后, 一直等待客户端的请求 while (true) { // 接收到请求时, 创建一个Socket对象 Socket socket = serverSocket.accept(); System.out.println("接收到请求,connected from " + socket.getRemoteSocketAddress()); // 开启线程处理请求 Thread thread = new HandlerTest(socket); thread.start(); } } } class HandlerTest extends Thread { Socket socket; public HandlerTest(Socket socket) { this.socket = socket; } public void run() { try { // 获取输入流和输出流 InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); handle(inputStream, outputStream); } catch (Exception e) { try { this.socket.close(); }catch (IOException ioe) { ioe.printStackTrace(); } } } private void handle(InputStream inputStream, OutputStream outputStream) throws IOException { // 读取HTTP协议请求部分 BufferedReader bufferedReader = new BufferedReader(new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8)); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); // 读取HTTP请求 boolean requestOK = false; String first = bufferedReader.readLine(); // 判断请求是否正确 if (first.startsWith("GET / HTTP/1.1")) { requestOK = true; } while (true) { String header = bufferedReader.readLine(); // 读取到空行时, HTTP Header 读取完毕 if (header.isEmpty()) { break; } System.out.println(header); } System.out.println(requestOK ? "请求正常" : "请求不正常"); // 响应HTTP请求 if (!requestOK) { // 请求不正常, 返回错误信息 bufferedWriter.write("HTTP/1.1 404 Not Found\r\n"); bufferedWriter.write("Content-Type: text/html; charset=UTF-8\r\n"); bufferedWriter.write("\r\n"); bufferedWriter.write("<h1>404 Not Found</h1>"); } else { // 请求正常, 返回正常信息 // 读取html文件 InputStream htmlFile = Server.class.getClassLoader().getResourceAsStream("html/a.html"); BufferedReader htmlReader = new BufferedReader(new InputStreamReader(htmlFile)); // 读取html文件内容 StringBuilder data = new StringBuilder(); String line = null; while ((line = htmlReader.readLine()) != null) { data.append(line); } // 关闭html文件 htmlReader.close(); // 获取html文件内容长度 int contentLength = data.toString().getBytes(StandardCharsets.UTF_8).length; // 返回HTTP响应 bufferedWriter.write("HTTP/1.1 200 OK\r\n"); bufferedWriter.write("Connection: keep-alive\r\n"); bufferedWriter.write("Content-Type: text/html; charset=UTF-8\r\n"); bufferedWriter.write("Content-Length: " + contentLength + "\r\n"); // 响应头和响应体之间有一个空行 bufferedWriter.write("\r\n"); bufferedWriter.write(data.toString()); // 刷新缓冲区 bufferedWriter.flush(); } } }