第一步:实现基础 HTTP 服务器

在这一章中,我们将从零开始编写一个简单的 HTTP 服务器。这个服务器的基本功能是监听一个端口,接收来自客户端的 HTTP 请求,并返回一个 HTTP 响应。我们将使用 Java 的 ServerSocket 类来实现网络监听,并通过简单的 InputStreamOutputStream 来处理 HTTP 请求和响应。

1.1 创建基础 HTTP 服务器

我们的目标是创建一个能够监听客户端请求的 HTTP 服务器,并能返回一个简单的响应。我们将分为几个步骤:

  1. 创建一个 ServerSocket 监听端口:使用 ServerSocket 类来创建一个监听指定端口的服务器套接字。
  2. 接受客户端连接并接收请求:通过 Socket 接受客户端的连接,并从输入流读取 HTTP 请求。
  3. 发送 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 代码解析

  1. 创建 ServerSocket 实例
ServerSocket serverSocket = new ServerSocket(PORT);

这行代码创建了一个监听指定端口(本例为 8080)的 ServerSocket 实例。ServerSocket 是 Java 提供的一个用于监听客户端连接的类。

  1. 接受客户端连接
Socket clientSocket = serverSocket.accept();

通过调用 accept() 方法,服务器会阻塞并等待来自客户端的连接。一旦有客户端连接到服务器,就会返回一个 Socket 对象,代表与该客户端的连接。

  1. 读取 HTTP 请求
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String requestLine = reader.readLine();

通过输入流,我们从客户端读取 HTTP 请求的第一行(请求行),例如 GET / HTTP/1.1。这是 HTTP 请求的最基础信息,包含了请求方法、路径和 HTTP 版本。

  1. 发送 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 页面。

  1. 关闭连接
clientSocket.close();

每次处理完一个请求后,我们关闭与客户端的连接。

1.4 测试 HTTP 服务器

  1. 编译并运行 SimpleHttpServer 类。

  2. 在浏览器中访问 http://localhost:8080,你应该会看到一个显示 "Hello, World!" 的网页。

  3. 你也可以使用 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 服务器的奥秘的更多相关文章

  1. WEBGL 2D游戏引擎研发系列 第一章 <新的开始>

    WEBGL 2D游戏引擎研发系列 第一章 <新的开始> ~\(≥▽≤)/~HTML5游戏开发者社区(群号:326492427) 转载请注明出处:http://html5gamedev.or ...

  2. 第一章. ActionScript 语言基础

    第一章. ActionScript 语言基础 1.0. ActionScript 3.0 Cookbook 概述 1.1. 新建一个 ActionScript project 1.2. 自己定义应用程 ...

  3. 第一章 oracle数据库基础

    第一章   oracle数据库基础 1.oracle简介-->数据库管理系统    1.1:数据库    1.2:全局数据库名    1.3:数据库实例    1.4:表空间    1.5:数据 ...

  4. 第一章 C++编程基础

    第一章 C++编程基础 1.1 如何撰写C++程序 赋值 assignment复合赋值 (compound assignment) += 函数(function)是一块独立的程序代码序列(code s ...

  5. 回顾PHP:第一章:PHP基础语法

    第一章:PHP基础语法 一.常量: 1.1.define()函数:define(‘R’,’5’,’true’); //R:常量名,5:常量值,true:常量名对大小写不敏感,为false时表示对常量名 ...

  6. JAVA 入门第一章(语法基础)

    本人初学java 博客分享记录一下自己的学习历程 java我的初步学习分为六章,有c和c++的基础学起来也简便了很多. 第一章 语法基础 第二章 面向对象 第三章 常用工具类 第四章 文件操纵 第五章 ...

  7. jQuery系列 第一章 jQuery框架简单介绍

    第一章 jQuery框架简单介绍 1.1 jQuery简介 jQuery是一款优秀的javaScript库(框架),该框架凭借简洁的语法和跨平台的兼容性,极大的简化了开发人员对HTML文档,DOM,事 ...

  8. Python 学习系列----第一章:基础知识

    1.1 常量-----不能改变它的值 1.2 数 在Python 中数可以分为整数.浮点数和复数. PS:在Python中不用区分'long int'类型.默认的整数类型可以任意长.(译者注:长度应该 ...

  9. go基础系列 第一章 go基础语法

    0.前言 1. go定义变量的几种方式 2. go内建变量类型 3. 常量的定义 4. go枚举 5. go的if语句 零. go语言的换行 go语言对换行很有讲究, 如果想换行,必须有一个逗号, 否 ...

  10. 《Java从入门到失业》第一章:计算机基础知识(三):程序语言简介

    1.3程序语言简介 我们经常会听到一些名词:低级语言.高级语言.编译型.解释型.面向过程.面向对象等.这些到底是啥意思呢?在正式进入Java世界前,笔者也尝试简单的聊一聊这块东西. 1.3.1低级语言 ...

随机推荐

  1. C# and TypeScript – Enum Flags

    前言 以前就有提过 Enum Flags,但平日不常用.最近翻 Angular 源码,发现它很多地方用到,而且没有封装语义代码.一堆符号真的看不惯啊... 于是又去复习了一遍,熟悉熟悉.顺便写一篇做记 ...

  2. C++ char*类型与vector类型的相互转换

    char*类型与vector<char> 类型的相互转换 很多时候需要使用动态的字符串,但是char*难以完成相应的扩容操作,而动态数组vector则可以简单地完成,结合二者特性就可以完成 ...

  3. MyBatis——案例——添加

    添加   1.编写接口方法:Mapper接口     参数:除了 id 之外的所有数据     结果:void /** * 添加 */ void add(Brand brand);   2.编写SQL ...

  4. 神经网络之卷积篇:详解为什么使用卷积?(Why convolutions?)

    详解为什么使用卷积? 来分析一下卷积在神经网络中如此受用的原因,然后对如何整合这些卷积,如何通过一个标注过的训练集训练卷积神经网络做个简单概括.和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀 ...

  5. 暑假集训CSP提高模拟5

    听好了: 7 月 22 日,比样的学长就此陷落.每个陷落的学长都将迎来一场模拟赛,为这些模拟赛带来全新的题面. 你所熟知的一切都将改变,你所熟悉的算法都将加诸比样的考验. 至此,一锤定音. 尘埃,已然 ...

  6. USB协议详解第8讲(USB描述符-字符串和语言ID描述符)

    1.字符串描述符相关概念 字符串描述符:首先,字符串描述符就是用字符串描述一个设备的一些属性,毕竟人能看懂的是字符,而不是十六进制,描述的属性包括设备厂商名字.产品名字.产品序列号.各个配置名字.各个 ...

  7. FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频

    ​Android早期的MediaPlayer控件对于网络视频的兼容性很差,所以后来单独推出了Exoplayer库增强支持网络视频,在<Android Studio开发实战:从零基础到App上线( ...

  8. KubeSphere DevOps 系统功能实战

    James,Java 工程师,喜欢学习和记录当下热门技术并验证其优势和缺点,以及当下火热的云原生解决方案的实施与推广. 前言 基于 Jenkins 的 KubeSphere DevOps 系统是专为 ...

  9. tmux从入门到装x

    原文: https://blog.csdn.net/CSSDCC/article/details/121231906 安装方法: # Ubuntu 或 Debian $ sudo apt-get in ...

  10. python项目实战(二手房屋出租系统)

    文章目录 1.系统概述 2.技术栈 3.系统功能 4.核心代码分析 5. 代码实现 6.实现细节 6.未来改进方向 在当今数字化时代,自动化和数字化管理工具对于提高效率至关重要.在这篇博客中,我们将一 ...