MiniTomcat 系列:第一章:解锁实现基础 HTTP 服务器的奥秘
第一步:实现基础 HTTP 服务器
在这一章中,我们将从零开始编写一个简单的 HTTP 服务器。这个服务器的基本功能是监听一个端口,接收来自客户端的 HTTP 请求,并返回一个 HTTP 响应。我们将使用 Java 的 ServerSocket 类来实现网络监听,并通过简单的 InputStream 和 OutputStream 来处理 HTTP 请求和响应。
1.1 创建基础 HTTP 服务器
我们的目标是创建一个能够监听客户端请求的 HTTP 服务器,并能返回一个简单的响应。我们将分为几个步骤:
- 创建一个 ServerSocket 监听端口:使用
ServerSocket类来创建一个监听指定端口的服务器套接字。 - 接受客户端连接并接收请求:通过
Socket接受客户端的连接,并从输入流读取 HTTP 请求。 - 发送 HTTP 响应:构建一个简单的 HTTP 响应并通过输出流发送给客户端。
1.2 实现代码
import java.io.*;
import java.net.*;
public class SimpleHttpServer {
private static final int PORT = 8080;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("HTTP Server is running on port " + PORT);
while (true) {
// 接受客户端连接
Socket clientSocket = serverSocket.accept();
System.out.println("New connection from " + clientSocket.getInetAddress());
// 获取输入流,读取客户端请求
InputStream inputStream = clientSocket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String requestLine = reader.readLine();
if (requestLine != null) {
System.out.println("Request: " + requestLine);
}
// 构建一个简单的 HTTP 响应
OutputStream outputStream = clientSocket.getOutputStream();
PrintWriter writer = new PrintWriter(outputStream, true);
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type: text/html; charset=UTF-8");
writer.println(); // 空行,表示响应头结束
writer.println("<html>");
writer.println("<head><title>Simple HTTP Server</title></head>");
writer.println("<body><h1>Hello, World!</h1></body>");
writer.println("</html>");
// 关闭连接
clientSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.3 代码解析
- 创建 ServerSocket 实例:
ServerSocket serverSocket = new ServerSocket(PORT);
这行代码创建了一个监听指定端口(本例为 8080)的 ServerSocket 实例。ServerSocket 是 Java 提供的一个用于监听客户端连接的类。
- 接受客户端连接:
Socket clientSocket = serverSocket.accept();
通过调用 accept() 方法,服务器会阻塞并等待来自客户端的连接。一旦有客户端连接到服务器,就会返回一个 Socket 对象,代表与该客户端的连接。
- 读取 HTTP 请求:
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String requestLine = reader.readLine();
通过输入流,我们从客户端读取 HTTP 请求的第一行(请求行),例如 GET / HTTP/1.1。这是 HTTP 请求的最基础信息,包含了请求方法、路径和 HTTP 版本。
- 发送 HTTP 响应:
PrintWriter writer = new PrintWriter(outputStream, true);
writer.println("HTTP/1.1 200 OK");
writer.println("Content-Type: text/html; charset=UTF-8");
writer.println();
writer.println("<html>");
writer.println("<head><title>Simple HTTP Server</title></head>");
writer.println("<body><h1>Hello, World!</h1></body>");
writer.println("</html>");
构建一个简单的 HTTP 响应,响应内容为一个 HTML 页面,显示 "Hello, World!"。首先,我们发送 HTTP 响应的状态行,紧接着发送响应头(如 Content-Type)。响应体部分包含了一个简单的 HTML 页面。
- 关闭连接:
clientSocket.close();
每次处理完一个请求后,我们关闭与客户端的连接。
1.4 测试 HTTP 服务器
编译并运行
SimpleHttpServer类。在浏览器中访问
http://localhost:8080,你应该会看到一个显示 "Hello, World!" 的网页。你也可以使用 curl 命令来测试服务器:
curl http://localhost:8080
1.5 总结
通过这一章,我们实现了一个非常简单的 HTTP 服务器,能够监听来自客户端的请求,并返回一个静态的 HTML 页面。这个 HTTP 服务器只是一个最基本的框架,但它为我们后续增加更多功能(如静态文件支持、Servlet 容器等)奠定了基础。
在下一章,我们将开始解析 HTTP 请求,并支持静态文件的提供。
文章出处:
https://zthinker.com/archives/di-1bu-shi-xian-ji-chu-http-fu-wu-qi
项目源代码地址:
https://github.com/daichangya/MiniTomcat/tree/chapter1/mini-tomcat
作者:代老师的编程课
出处:https://zthinker.com/
如果你喜欢本文,请长按二维码,关注 Java码界探秘
.
MiniTomcat 系列:第一章:解锁实现基础 HTTP 服务器的奥秘的更多相关文章
- WEBGL 2D游戏引擎研发系列 第一章 <新的开始>
WEBGL 2D游戏引擎研发系列 第一章 <新的开始> ~\(≥▽≤)/~HTML5游戏开发者社区(群号:326492427) 转载请注明出处:http://html5gamedev.or ...
- 第一章. ActionScript 语言基础
第一章. ActionScript 语言基础 1.0. ActionScript 3.0 Cookbook 概述 1.1. 新建一个 ActionScript project 1.2. 自己定义应用程 ...
- 第一章 oracle数据库基础
第一章 oracle数据库基础 1.oracle简介-->数据库管理系统 1.1:数据库 1.2:全局数据库名 1.3:数据库实例 1.4:表空间 1.5:数据 ...
- 第一章 C++编程基础
第一章 C++编程基础 1.1 如何撰写C++程序 赋值 assignment复合赋值 (compound assignment) += 函数(function)是一块独立的程序代码序列(code s ...
- 回顾PHP:第一章:PHP基础语法
第一章:PHP基础语法 一.常量: 1.1.define()函数:define(‘R’,’5’,’true’); //R:常量名,5:常量值,true:常量名对大小写不敏感,为false时表示对常量名 ...
- JAVA 入门第一章(语法基础)
本人初学java 博客分享记录一下自己的学习历程 java我的初步学习分为六章,有c和c++的基础学起来也简便了很多. 第一章 语法基础 第二章 面向对象 第三章 常用工具类 第四章 文件操纵 第五章 ...
- jQuery系列 第一章 jQuery框架简单介绍
第一章 jQuery框架简单介绍 1.1 jQuery简介 jQuery是一款优秀的javaScript库(框架),该框架凭借简洁的语法和跨平台的兼容性,极大的简化了开发人员对HTML文档,DOM,事 ...
- Python 学习系列----第一章:基础知识
1.1 常量-----不能改变它的值 1.2 数 在Python 中数可以分为整数.浮点数和复数. PS:在Python中不用区分'long int'类型.默认的整数类型可以任意长.(译者注:长度应该 ...
- go基础系列 第一章 go基础语法
0.前言 1. go定义变量的几种方式 2. go内建变量类型 3. 常量的定义 4. go枚举 5. go的if语句 零. go语言的换行 go语言对换行很有讲究, 如果想换行,必须有一个逗号, 否 ...
- 《Java从入门到失业》第一章:计算机基础知识(三):程序语言简介
1.3程序语言简介 我们经常会听到一些名词:低级语言.高级语言.编译型.解释型.面向过程.面向对象等.这些到底是啥意思呢?在正式进入Java世界前,笔者也尝试简单的聊一聊这块东西. 1.3.1低级语言 ...
随机推荐
- C# and TypeScript – Enum Flags
前言 以前就有提过 Enum Flags,但平日不常用.最近翻 Angular 源码,发现它很多地方用到,而且没有封装语义代码.一堆符号真的看不惯啊... 于是又去复习了一遍,熟悉熟悉.顺便写一篇做记 ...
- C++ char*类型与vector类型的相互转换
char*类型与vector<char> 类型的相互转换 很多时候需要使用动态的字符串,但是char*难以完成相应的扩容操作,而动态数组vector则可以简单地完成,结合二者特性就可以完成 ...
- MyBatis——案例——添加
添加 1.编写接口方法:Mapper接口 参数:除了 id 之外的所有数据 结果:void /** * 添加 */ void add(Brand brand); 2.编写SQL ...
- 神经网络之卷积篇:详解为什么使用卷积?(Why convolutions?)
详解为什么使用卷积? 来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集训练卷积神经网络做个简单概括.和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀 ...
- 暑假集训CSP提高模拟5
听好了: 7 月 22 日,比样的学长就此陷落.每个陷落的学长都将迎来一场模拟赛,为这些模拟赛带来全新的题面. 你所熟知的一切都将改变,你所熟悉的算法都将加诸比样的考验. 至此,一锤定音. 尘埃,已然 ...
- USB协议详解第8讲(USB描述符-字符串和语言ID描述符)
1.字符串描述符相关概念 字符串描述符:首先,字符串描述符就是用字符串描述一个设备的一些属性,毕竟人能看懂的是字符,而不是十六进制,描述的属性包括设备厂商名字.产品名字.产品序列号.各个配置名字.各个 ...
- FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
Android早期的MediaPlayer控件对于网络视频的兼容性很差,所以后来单独推出了Exoplayer库增强支持网络视频,在<Android Studio开发实战:从零基础到App上线( ...
- KubeSphere DevOps 系统功能实战
James,Java 工程师,喜欢学习和记录当下热门技术并验证其优势和缺点,以及当下火热的云原生解决方案的实施与推广. 前言 基于 Jenkins 的 KubeSphere DevOps 系统是专为 ...
- tmux从入门到装x
原文: https://blog.csdn.net/CSSDCC/article/details/121231906 安装方法: # Ubuntu 或 Debian $ sudo apt-get in ...
- python项目实战(二手房屋出租系统)
文章目录 1.系统概述 2.技术栈 3.系统功能 4.核心代码分析 5. 代码实现 6.实现细节 6.未来改进方向 在当今数字化时代,自动化和数字化管理工具对于提高效率至关重要.在这篇博客中,我们将一 ...