构建简单的仿tomcat Web服务器之Socket基本请求响应
一、实现目标二、功能实现三、测试1、服务启动2、浏览器请求&响应3、服务端日志
四、说明总结
一、实现目标
在解析Java网络编程基础:理解tomcat的原理 中,简单分析了socket通信的实现,分析完后,有提到结合浏览器的请求响应信息格式,欢迎大家动手实现一个类似tomcat的web服务。 “基于这样的原理,结合浏览器的请求,响应格式(如下图所示),相信你一定可以轻松手写一个简单的tomcat来接收浏览器发送的请求,并进行响应,欢迎动手实战”
实现类似Tomcat的功能涉及到创建一个简单的Web服务器,用于接收HTTP请求并返回响应。下面是我基于Java Socket实现类似tomcat的web server的简单例子,实现了简易的Web服务器,能够处理GET请求并返回一个简单的HTML页面。
二、功能实现
简单的web服务器SimpleWebServer实现类如下:
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// 仿tomcat简单web server,用于接收客户端请求,并给出固定响应
public class SimpleWebServer {
public static void main(String[] args) {
int port = 9000;
// 创建ServerSocket的对象,注册端口
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("-----服务端启动成功,监听端口为 " + port + "-------");
// 创建出一个线程池,负责处理通信管道的任务。
ExecutorService pool = Executors.newFixedThreadPool(10);
while (true) {
// serverSocket阻塞等待客户端的连接请求
Socket socket = serverSocket.accept();
// 分别使用独立的线程处理每个客户端请求,提升服务端处理请求的吞吐量。
pool.execute(new SocketRunnable(socket));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
单个客户端请求处理线程类如下:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
//封装用于处理单个客户端请求的线程
public class SocketRunnable implements Runnable {
private Socket socket;
public SocketRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream())) {
String requestLine = br.readLine();
System.out.println("收到客户端" + socket.getRemoteSocketAddress() + ":" + socket.getPort() + " 请求: " + requestLine);
// 根据浏览器响应格式逐行输出响应
ps.println("HTTP/1.1 200 OK");
ps.println("Content-Type:text/html;charset=UTF-8");
ps.println(); // 输出内容之前必须换行,浏览器响应固定格式
ps.println("
Hello, this is a simple web server like tomcat!
");ps.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
如上代码可以看到服务端使用线程池,对每个客户端的每次请求都交给线程池中单独的线程处理,以提升web server的吞吐量。
三、测试
1、服务启动
2、浏览器请求&响应
3、服务端日志
四、说明总结
这个简易的Web服务器会在本地监听9000端口。当有HTTP请求到达时,它会创建一个线程用于处理客户端的请求,输出请求内容,并响应固定的一句"Hello, this is a simple web server like tomcat!"的HTML页面,并将处理线程交给线程池管理。请注意,实际的Web服务器需要更多的特性,例如处理不同的HTTP方法、文件处理,动态内容生成、安全性等。本例只是一个入门级别的例子,用于演示基本的请求和响应处理,感兴趣的同学可以阅读tomcat源码,深入理解。
相关链接
发表评论