简易Web服务器实现
Posted JobsandCzj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简易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,多线程,大家都可以试着实现一下。
以上是关于简易Web服务器实现的主要内容,如果未能解决你的问题,请参考以下文章