简易Web服务器实现

手痒就自己实现了一下简易的web服务器,由于只是简易的web服务器,所以并没有什么特别高深的技术含量。

1.      TCP通信(socket)

2.      IO流

3.      线程池技术

服务器架构也简单:

Request类主要是实现解析URL的功能,以获取html文件的路径。

Response类实现读取html文件并且向浏览器输出html文件内容。

Server类整合Request类和Response类,实现线程的run方法。

Test类实现线程池,同时也是服务启动类。

下图是浏览器发给服务器的内容:

下面是效果图:

1.服务器输出的日志

页面效果图:

下面贴一些关键代码:

package request;

import java.io.BufferedReader;
import java.io.IOException;

public class Request {
	private String fileroute=null;
	private BufferedReader br=null;

	public Request(BufferedReader br) {
		this.br=br;
	}
	public void parse(){

		String info=null;
		StringBuffer msg=new StringBuffer();
		try {

			while((info=br.readLine())!=null && info.length()>0){//循环读取客户端的信息
				msg.append(info);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		fileroute=parseFileroute(msg.toString());
	}
	//由浏览器发给服务器内容的规律进行读取文件路径
	private String parseFileroute(String requestString) {
        int index1, index2;
        index1 = requestString.indexOf(‘ ‘);
        if (index1 != -1) {
            index2 = requestString.indexOf(‘ ‘, index1 + 1);
            if (index2 > index1)
                return requestString.substring(index1 + 1, index2);
        }
        return null;
    }
	//获取html文件名
	public String getFileroute(){
		return fileroute;
	}
}
package response;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Response {
	private PrintWriter pw=null;
	private String fileroute=null;

	public Response(PrintWriter pw, String fileroute) {
		this.pw=pw;
		this.fileroute=fileroute;
	}

	public void doresponse() {
		File file=new File("webapp"+fileroute);
//		System.out.println(file.getAbsolutePath());
		if(!file.exists() || !file.isFile()) //不是文件或不存在
			return;

		FileInputStream is=null;
		InputStreamReader isr=null;
		BufferedReader br=null;

		try {
			is=new FileInputStream(file);
			isr=new InputStreamReader(is);
			br=new BufferedReader(isr);
			String info;
			StringBuffer msg=new StringBuffer();
			while((info=br.readLine())!=null && info.length()>0){//循环读取html文件内容
				msg.append(info);
			}
			//将文件内容输出到浏览器
			pw.write(msg.toString());
			pw.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			//关闭资源
			try {
				if(br!=null)
					br.close();
				if(isr!=null)
					isr.close();
				if(is!=null)
					is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}
}
package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

import request.Request;
import response.Response;

/*
 * 基于TCP协议的Socket通信,实现用户登陆
 * 服务器端
 */
public class Server implements Runnable {
	private Socket socket=null;
	public Server(Socket socket) {
		this.socket=socket;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()); //输出当前线程名字
		InputStream is=null;
		InputStreamReader isr=null;
		BufferedReader br=null;
		OutputStream os=null;
		PrintWriter pw=null;
		//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
		try {

			//接收请求 进入阻塞状态
			InetAddress address=socket.getInetAddress();
			System.out.println("当前客户端的IP:"+address.getHostAddress());
			System.out.println("当前客户端端口:" + socket.getPort());

			is=socket.getInputStream();
			isr=new InputStreamReader(is);
			br=new BufferedReader(isr);

			Request request = new Request(br);
			request.parse();

			os = socket.getOutputStream();
			pw = new PrintWriter(os);
			Response response = new Response(pw, request.getFileroute());
			response.doresponse();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {
			//关闭资源
			try {
				if(pw!=null)
					pw.close();
				if(os!=null)
					os.close();
				if(br!=null)
					br.close();
				if(isr!=null)
					isr.close();
				if(is!=null)
					is.close();
				if(socket!=null)
					socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
package test;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import server.Server;

public class Test {

	public static void main(String[] args) {
		ExecutorService pool=null;
		ServerSocket serverSocket=null;
		try {
			serverSocket=new ServerSocket(80);
			// 创建一个可重用固定线程数的线程池 线程数为5
		    pool = Executors.newFixedThreadPool(5);
			Socket socket=null;
			while(true) {
				socket=serverSocket.accept();

//				new Thread(new Server(socket)).start();
				pool.execute(new Server(socket));
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(pool!=null)
				pool.shutdown();
			try {
				if(serverSocket!=null)
					serverSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

一个不错的练手项目,涉及到JAVA的IO,Socket,多线程,大家都可以试着实现一下。

时间: 2024-10-13 18:18:31

简易Web服务器实现的相关文章

Socket 初识 用Socket建立一个简易Web服务器

摘自<Asp.Net 本质论>作者:郝冠军 //在.Net中.system.Net命名空间提供了网络编程的大多数数据据类型以及常用操作,其中常用的类型如下:/*IPAddress 类表示一个IP地址* IPEndPoint类用来表示一个IP地址和一个端口号的组合,成为网络的端点.* System.Net.Sockets命名空间中提供了基于Socked编程的数据类型.* Socket类封装了Socked的操作.* 常见的操作:* Listen:设置基于连接通信的Socket进入监听状态,并设置等

TinyWS —— 一个C++写的简易WEB服务器(一)

写在前面 每个码农可能都会偶尔有自己做一个常用软件的想法,比如操作系统,编译器,邮件服务器/客户端,文字编辑器等等.这里面有些很难,比如操作系统,做一个最简单的也要付出很大的努力,可是大部分常用工具都是可以比较容易的做一个简易版本(当然也是只能玩玩而已).于是我做了一个非常简陋的WEB服务器 —— TinyWS.这里主要是记录下自己整个过程中的一些想法. TinyWS是用C++”从头开始“做的,也就是说,除了C/C++的标准库和操作系统的系统调用,并没有使用第三方库.我并不喜欢C++(甚至有些厌

[js高手之路]node js系列课程-创建简易web服务器与文件读写

web服务器至少有以下几个特点: 1.24小时不停止的工作,也就是说这个进程要常驻在内存中 2.24小时在某一端口监听,如: http://localhost:8080, www服务器默认端口80 3.要能够处理基本的请求:如get, post 在node js中创建一台服务器非常的简单,因为node自带http模块,该模块可以帮助我们非常快速搭建一台web服务器,来处理一个简单的请求. 1 const http = require("http"); 2 var server = ht

写一个简易web服务器、ASP.NET核心知识(4)

前言 昨天尝试了,基于对http协议的探究,我们用控制台写了一个简单的浏览器.尽管浏览器很low,但是对于http协议有个更好的理解. 说了上面这一段,诸位猜到我要干嘛了吗?(其实不用猜哈,标题里都有,又都不瞎...我就是调侃一下,说些没营养的笑话.我认为这样能不那么枯燥,尽管不好笑吧,但这不重要!) 没错,今天要尝试的东西,是自己写一个web服务器.初衷依旧和昨天一样,旨在理解一些东西,而不是真的写出一个多牛的东西. 第一次尝试(V1.0) 1.理论支持 其实关于http协议的理论方面我在<写

TinyWS —— 一个C++写的简易WEB服务器(三)

写在前面 代码已经托管在 https://git.oschina.net/augustus/TinyWS.git 可以用git clone下来.由于我可能会偶尔做一些修改,不能保证git 库上的代码与blog里的完全一致(实际上也不可能把所有的代码都贴在这里).另外,TinyWS是基于linux写的(ubuntu 14.10 + eclipse luna,eclipse工程我也push到了git库),故在Windows上可能无法正常编译(主要是系统调用 部分可能会不同). 前面的内容可参考上一篇

python简易web服务器学习笔记(三)

import sys, os, BaseHTTPServer #------------------------------------------------------------------------------- class ServerException(Exception): '''For internal error reporting.''' pass #--------------------------------------------------------------

python简易web服务器学习笔记(二)

import BaseHTTPServer #------------------------------------------------------------------------------- class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): '''Respond to HTTP requests with info about the request.''' # Template for page to sen

Python实现简易Web服务器

 1.请自行了解HTTP协议 http://www.cnblogs.com/reboot51/p/8358129.html(点击跳转) 2.创建Socket服务,监听指定IP和端口 3.以阻塞方式等待客户端连接 4.读取客户端请求数据并进行解析 5.准备服务器运行上下文 6.处理客户端请求数据 7.根据用户请求路径读取文件 8.返回响应结果给客户端 9.程序入口 10.目录结构 11.运行 python wsgiserver.py app:run 12.源码 a.wsgiserver.py文件

TinyWS —— 一个C++写的简易WEB服务器(二)

写在前面 代码已经托管在 https://git.oschina.net/augustus/TinyWS.git 可以用git clone下来.由于我可能会偶尔做一些修改,不能保证git 库上的代码与blog里的完全一致(实际上也不可能把所有的代码都贴在这里).另外,TinyWS是基于linux写的(ubuntu 14.10 + eclipse luna,eclipse工程我也push到了git库),故在Windows上可能无法正常编译(主要是系统调用 部分可能会不同). 前面的内容可参考上一篇