1. Http服务基本要素
1.1 监听连接
浏览器每发起一次请求都需要跟服务端建立连接,服务端要时刻监听有没有客户端连接。传输层协议有 TCP/UDP 两种,实现起来并没有强制说用哪一种,下面是官方文档对 Http 连接的说明:
文档中指明了连接通常用的是 TCP, TCP 不用考虑数据包乱序,丢失这些问题,实现起来更简单,高效。在代码层我们可以用 Socket 来实现我们的 TCP 传输服务。
1.2 接收数据
Socket 监听连接,在没有连接到来之前一直是阻塞在 serverSocket.accept();
有请求过来就可以运行到下面的代码,然后可以根据我们的输入流读取信息,根据 Http 协议拆开获取我们要的请求数据。
1.3 返回数据
根据业务处理完获得返回实体数据,然后遵从 Http 协议格式构造返回的消息报文。浏览器获得到的数据也会根据 Http 协议进行渲染。
2. Http报文格式
Http 协议请求报文的本质就是一堆字符串,只是这堆字符是有格式的,发送方跟接收方都需要按照这个格式来拼接和拆解内容。我们要实现一个 Web 服务,了解这个是最基本的要素。
以下截图的报文是通过 tcpflow
(一款功能强大的、基于命令行的免费开源工具)在 Linux 系统抓包获取的。
- 1
2.1 Request
图中各种请求首部字段的具体含义/用途,会在下面章节中详细讲解到。
2.2 Response
一般情况下,服务器收到客户端的请求后,就会有一个 Http 的响应消息,Http 响应也由 4 部分组成,分别是:状态行、响应头、空行 和 响应实体。
图中的首部字段和返回内容(响应实体)中间是有一个空行的。
3. 实现
3.1 效果
- Web 服务端监听 8090 端口;
- 本地浏览器访问 8090 页面显示
hello tomcat
。
3.2 代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
上面的代码初学者可以自己模仿着写一个,相信对 Http 会有很深刻的体验。代码中主要是监听连接,客户端连接后,根据 Http 协议进行字符串的拼接返回给客户端,客户端浏览器接收到是标准的 Http 格式就会进行渲染。
4. 小结
这边的代码虽然很简单,但是最核心的 Http 服务雏形已经展示出来了,成熟的 Http 服务可以在这基础上对以下模块进行优化:
- 针对请求事件的 线程 / IO 优化;
- Servlet 协议支持;
- 配置独立管理;
- Http协议内容完善(比如缓存机制);
- 支持虚拟主机配置;
- 支持代理;
- rewrite 机制;
- 安全认证。