使用ServerSocket和Thread写一个简单的web服务器小程序,山寨版Tomcat

本文介绍了一个简单的Web服务器小程序,使用Java实现。服务器监听80端口,通过多线程处理并发的浏览器请求,获取并反馈请求信息。适用于初学者理解Web服务器及浏览器请求的基本原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:写一个模拟服务器小程序,当服务器开启后,多个浏览器客户端可以并发访问,服务器获取浏览器的请求信息,并反馈信息给浏览器。

效果如下:

编译并开启(运行)服务器,服务器处于阻塞状态,等待浏览器的访问

谷歌浏览器访问成功:

服务端的访问信息:

一个浏览器访问结束后,服务端继续处于阻塞状态等待下一次的访问

火狐浏览器访问成功:

IE浏览器访问成功:

 

技术要点:

1,创建ServerSocket服务器,定义端口号为80;

2,创建通用的处理浏览器请求并反馈数据的对象,此处为利用多线程,故实现runnable接口重写run方法;

3,为实现多个不确定的请求,所以写一个while(true)循环,当服务器接收到一个请求,就创建一个线程并启动。

 

代码如下:

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.Runnable;

class CheapCopyServer 
{
	public static void main(String[] args) throws IOException
	{
		ServerSocket ss=new ServerSocket(80);

		while(true){
			Socket s=ss.accept();
			new Thread(new BrowserClient(s)).start();
		}

	}
}

class BrowserClient implements Runnable
{
	private Socket s;

	public BrowserClient(Socket s){
		this.s=s;
	}

	@Override
	public void run(){
		try{
			String ip=s.getInetAddress().getHostAddress();
			System.out.println(ip+"......connected");
			
			InputStream in=s.getInputStream();
			byte[] buf=new byte[1024];
			int len=in.read(buf);
			String text=new String(buf,0,len);
			System.out.println(text);

			PrintWriter out = new PrintWriter(s.getOutputStream(),true);
			out.println("<font color='#0000ff' size='5'>连接成功!</font>");

			s.close();
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException("出错啦^_^");
		}
		
	}
}

很简单的一个小程序,可以很入门地研究一下web服务器的工作原理,浏览器的请求原理。

 

 

 

<think>好的,用户让我介绍如何用Java一个基于线程池的Web服务器。首先,我需要确定用户的需求是什么。他们可能想要了解基本的实现原理,或者需要具体的代码示例。用户提到线程池,说明他们对并发处理有一定了解,但可能想优化服务器性能。 接下来,我应该回忆Java中与线程池相关的类,比如ExecutorService,以及如何处理HTTP请求。可能需要使用ServerSocket来监听端口。然后,每个连接请求到来时,线程池分配线程处理,这样可以避免频繁创建销毁线程的开销。 用户是Web服务器,所以需要处理HTTP协议的基本解析,比如读取请求,发送响应。可能需要解析请求方法、路径,然后返回对应的资源,比如简单的HTML或者文本。 需要分步骤讲解:创建线程池,建立ServerSocket,循环接受连接,将任务提交给线程池。然后处理请求的部分,包括读取输入流,解析请求行,生成响应内容,发送回客户端。 还要考虑异常处理,比如IO异常,以及关闭资源,如Socket线程池的正确关闭。可能还要提到如何测试,比如用浏览器访问localhost:端口。 可能需要注意的地方是,线程池的参数配置,比如核心线程数、最大线程数,根据服务器的需求调整。另外,这个示例是基础版,实际生产环境可能需要更复杂的处理,比如多路复用IO或者使用NIO,但用户可能只需要一个简单的示例。 需要确保代码结构清晰,步骤明确,解释每个部分的作用。同时提醒用户这只是教学示例,真实环境需要更多功能,比如处理不同的HTTP方法、错误处理、MIME类型支持等。 最后,总结实现步骤,强调线程池的优势,比如资源复用、控制并发数,提高服务器性能。</think>以下是一个基于Java线程池的Web服务器的实现步骤核心代码示例: --- ### 一、实现原理 1. **线程池作用**:复用线程资源,避免频繁创建/销毁线程开销 2. **处理流程**: - 主线程持续监听端口 - 收到请求后,将任务交给线程池处理 - 工作线程处理HTTP请求并返回响应 --- ### 二、核心代码实现 ```java import java.net.*; import java.io.*; import java.util.concurrent.*; public class ThreadPoolWebServer { // 创建固定大小的线程池 private static final ExecutorService threadPool = Executors.newFixedThreadPool(10); public static void main(String[] args) throws IOException { try (ServerSocket serverSocket = new ServerSocket(8080)) { System.out.println("服务器启动,监听端口 8080..."); while (true) { final Socket clientSocket = serverSocket.accept(); // 将任务提交给线程池 threadPool.execute(() -> handleRequest(clientSocket)); } } } private static void handleRequest(Socket clientSocket) { try (BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); OutputStream out = clientSocket.getOutputStream()) { // 读取HTTP请求 String requestLine = in.readLine(); System.out.println("收到请求: " + requestLine); // 构建HTTP响应 String response = "HTTP/1.1 200 OK\r\n\r\n" + "<html><body><h1>Hello ThreadPool Server!</h1></body></html>"; out.write(response.getBytes()); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } ``` --- ### 三、关键组件解析 1. **`ServerSocket`** - 监听指定端口(示例使用8080) - 接受客户端连接请求 2. **`ExecutorService`** - 使用`newFixedThreadPool(10)`创建包含10个工作线程的池 - 通过`execute()`方法提交任务 3. **请求处理流程** - 读取请求头(示例仅读取第一行) - 构建包含简单HTML的HTTP响应 - 通过输出流返回响应 --- ### 四、测试方法 1. 编译运行程序 2. 浏览器访问 `http://localhost:8080` 3. 控制台会输出请求日志: ```shell 收到请求: GET / HTTP/1.1 ``` --- ### 五、优化建议 1. **动态线程池**:改用`ThreadPoolExecutor`自定义参数 ```java new ThreadPoolExecutor(10, 50, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); ``` 2. **异常处理**:增加HTTP 500错误处理 3. **资源处理**:实现静态文件读取 4. **协议完善**:支持更多HTTP方法头部信息 --- ### 六、与传统实现的对比 | 方案 | 优势 | 劣势 | |-----------|-----------------------------|---------------------| | 线程池方案 | 资源复用,适合高并发场景 | 线程数固定可能成为瓶颈 | | 每请求一线程方案 | 实现简单 | 线程创建开销大,不适合高并发场景 | | NIO方案 | 高并发支持好(如Netty框架) | 实现复杂度高 | 这个示例演示了最基础的实现,实际生产环境建议使用成熟的Web服务器(如Tomcat)或基于Netty/NIO实现高性能服务器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值