赞
踩
作为一个 Java 后端,提供 HTTP 服务可以说是基本技能之一了,但是你真的了解 HTTP 协议么?你知道知道如何手撸一个 HTTP 服务器么?Tomcat 的底层是怎么支持 HTTP 服务的呢?大名鼎鼎的 Servlet 又是什么东西呢,该怎么使用呢?
在初学 Java 时,Socket 编程是逃不掉的一章;虽然在实际业务项目中,使用这个的可能性基本为 0, 但并不意味着不用学。本篇将主要介绍如何使用 Socket 来实现一个简单的 HTTP 服务器,提供常见的 get/post 请求支持,并在此过程中了解下 HTTP 协议。
既然我们的目标是借助 Socket 来搭建 HTTP 服务器,那么我们首先需要确认两点,一是如何使用 Socket;另一个则是 HTTP 协议如何解析数据;下面分别进行说明。
我们这里主要是利用 ServerSocket 来绑定端口,提供 TCP 服务,基本使用姿势也比较简单,一般套路如下
ServerSocket serverSocket = new ServerSocket(port, ip)
serverSocket.accept();
// 接收请求数据
socket.getInputStream();
// 返回数据给请求方
out = socket.getOutputStream()
out.print(xxx)
out.flush();;
// 关闭连接
socket.close()
具体的代码,我们前面的章节详细地讲过了,第一次来的小伙伴可以戳链接去学习一下。
ServerSocket 走的是 TCP 协议,HTTP 协议本身是在 TCP 协议之上的一层。
TCP 是一种面向连接的、可靠的、基于字节流的传输层协议。TCP 在两个网络节点之间提供了一条可靠的通信信道,确保数据在传输过程中不会丢失、重复或乱序。TCP 使用握手过程建立连接,通过确认和重传机制确保数据可靠传输,并使用流量控制和拥塞控制算法来优化网络性能。
HTTP 是一个用于在 Web 浏览器和 Web 服务器之间传输超文本、图像、视频和其他媒体资源的应用层协议。HTTP 使用请求-响应模型,即客户端(通常是 Web 浏览器)发送请求给服务器,服务器处理请求并返回响应。HTTP 协议定义了一组方法(如 GET、POST、PUT、DELETE 等),用于指定请求的类型和目的。此外,HTTP 协议还定义了一组状态代码(如 200、404、500 等),用于表示响应的结果。
HTTP 协议依赖于 TCP 协议来传输数据。当 Web 浏览器向 Web 服务器发送 HTTP 请求时,它首先使用 TCP 协议与服务器建立连接。一旦连接建立,HTTP 请求消息会被封装在 TCP 数据包中,然后通过 TCP 信道发送给服务器。服务器收到 TCP 数据包后,解包提取 HTTP 请求消息,处理请求并生成 HTTP 响应消息。最后,HTTP 响应消息被封装在 TCP 数据包中,并通过相同的 TCP 信道发送回客户端。客户端收到 TCP 数据包后,解包提取 HTTP 响应消息并显示给用户。
这幅图展示了客户端(Web 浏览器)与服务器(Web 服务器)之间的 HTTP 请求和响应,它们通过可靠的、面向连接的 TCP 连接进行数据传输。
好,再说回 HTTP 服务器这件事,最需要关注的无非两点:
请求消息
HTTP 请求消息由请求行(Request Line)、请求头(Request Headers)、空行(Empty Line)、请求体(Request Body,可选)几个部分组成。
①、请求行又包含三个部分,HTTP 方法(例如 GET, POST, PUT, DELETE 等)、请求的目标 URL(通常是相对 URL,但也可以是绝对 URL)、HTTP 版本(例如 HTTP/1.1 或 HTTP/2),这些部分用空格分隔,例如:
GET /index.html HTTP/1.1
②、请求头是一系列以键值对表示的元数据,用于描述请求的附加信息。每个请求头占一行,键和值之间用冒号(:)分隔。请求头包含诸如 Host、User-Agent、Content-Type、Content-Length、Accept 等信息。例如:
Host: www.tobebetterjavaer.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
③、请求头和请求体之间有一个空行,表示请求头的结束。
④、对于某些 HTTP 方法(例如 POST、PUT 等),还可以在请求消息中包含请求体。请求体用于传输要发送给服务器的数据。请求体的格式和内容取决于 Content-Type 请求头的值。
例如,当提交 HTML 表单时,请求体可能如下所示:
username=恒二哥&password=123456
将这些部分放在一起,就构成了一个完整的 HTTP 请求消息:
POST /login HTTP/1.1
Host: Host: www.tobebetterjavaer.com
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
username=恒二哥&password=123456
响应消息
一个典型的 HTTP 响应消息由三部分组成:状态行(Status Line)、响应头(Response Headers)、响应体(Response Body)。
上面两张图,可以让你对 HTTP 请求和响应有个直观映象,接下来开始抓重点。
不管是请求消息还是响应消息,都可以划分为三部分,这就为我们后面的处理简化了很多工作。
接下来进入正题,基于 Socket 创建一个 HTTP 服务器,使用 Socket 基本没啥太大的问题,我们需要额外关注以下两点:
注意
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。