前段时间进一步了解webServer,因此听老大的话,自己实现了一个。
代码如下
WebServer类
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class WebServer { public static void main(String[] args) throws IOException { ExecutorService pool = Executors.newFixedThreadPool(4); ServerSocket ss = new ServerSocket(MyServ.HTTPPORT); ss.setReuseAddress(true); System.out.println("start..."); while (true) { Socket socket = ss.accept(); System.out.println("Thread #" + MyServ.count); pool.execute(new MyServ(socket)); } } }
MyServ类
import java.io.*;
import java.net.Socket;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
public class MyServ implements Runnable {
public static int count = 0; // 线程计数器
private static Random random = new Random(123);
private static ReentrantLock lock = new ReentrantLock(); // 重入锁
public static int HTTPPORT = 801;
private static String HOSTPATH = "D:/temp";
private static String ERRORPAGE = "/error.html";
private Socket socket;
public MyServ(Socket socket) {
this.socket = socket;
}
/**
* HTTP响应
*
* @param out
* @param request
*/
private void responseHTTP(PrintStream out, RequestZq request) {
File file = new File(HOSTPATH + request.getURI());
if (file.isDirectory()) {
autoGenerateBody(out, request, file);
return;
}
String response = getResponseHead(request);
// System.out.println(response.toString());
out.println(response.toString());
out.flush();
if (response.contains("404")) {
transferFile(out, HOSTPATH + ERRORPAGE);
} else {
transferFile(out, file.getPath());
}
}
private void autoGenerateBody(PrintStream out, RequestZq request, File file) {
StringBuffer response = new StringBuffer();
response.append(request.getReqVersion() + " 200 OK\r\n");
response.append("Content_Type:text/html");
System.out.println(response.toString());
out.println(response.toString());
out.println();
String[] list = file.list();
if (list.length == 0)
out.println("无文件");
else {
response = new StringBuffer();
response.append("<html><head><title>Directory</title></head><body><ul>");
for (int i = 0; i < list.length; i++) {
File f = new File(file.getAbsolutePath() + "/" + list[i]);
String path = f.getAbsolutePath();
int idx = path.indexOf(HOSTPATH) + HOSTPATH.length() + 1;
response.append("<li><a href=\""
+ path.substring(idx).replace('\\', '/') + "\">"
+ list[i] + "</a></li>");
}
response.append("</ul></body></html>");
//System.out.println(response.toString());
out.println(response.toString());
}
out.flush();
}
/**
* 获得HTTP的报文头
*
* @param request
* @return
*/
private String getResponseHead(RequestZq request) {
StringBuffer response = new StringBuffer();
File file;
String filepath = HOSTPATH + request.getURI();
int idx = request.getURI().lastIndexOf(".");
System.out.println(">>filePath = " + filepath);
file = new File(filepath.toString());
if (!file.exists() || idx == -1) {
response.append(request.getReqVersion() + " 404 Not Found\r\n");
return response.toString();
}
response.append(request.getReqVersion() + " 200 OK\r\n");
response.append("Content_Type:");
String type = request.getURI().substring(idx + 1,
request.getURI().length());
if ("jpg|png|gif|jpeg|bmp".contains(type)) {
response.append("image/" + type);
} else if ("shtml".contains(type)) {
response.append("text/html; charset=GBK");
} else {
response.append("error");
}
response.append("\r\n");
response.append("Content_Length:" + (file.length() + 2) + "\r\n");
return response.toString();
}
/**
* 传输http报文body
*
* @param request
*/
private void transferFile(PrintStream out, String filepath) {
File file = new File(filepath);
int len = (int) file.length() + 1;
try {
FileInputStream fs = new FileInputStream(file);
byte[] buf = new byte[len];
fs.read(buf);
out.write(buf);
out.flush();
fs.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
BufferedReader in = null;
PrintStream out = null;
increaseCount();
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintStream(socket.getOutputStream());
RequestZq request = null;
String reqStr = null;
// GET /xx HTTP/1.1
reqStr = in.readLine()+"\n";
request = new RequestZq(reqStr);
System.out.println(reqStr);
this.responseHTTP(out, request);
in.close();
out.close();
socket.close();
socket = null;
/*
* int curCount = getCount(); int i= 10; while (--i>0) {
* Thread.sleep(random.nextInt()%1000+1000);
* System.out.print(curCount); }
* System.out.println("\n------out: "+curCount); catch
* (InterruptedException e) { e.printStackTrace(); }
*/
} catch (IOException e) {
System.out.print(e.getMessage());
}
}
private int getCount() {
int ret = 0;
try {
lock.lock();
ret = count;
} finally {
lock.unlock();
}
return ret;
}
private void increaseCount() {
try {
lock.lock();
++count;
} finally {
lock.unlock();
}
}
}
RequestZq类
public class Factory {
private static Factory fac = null;
private Factory() {
}
public Factory getInstance() {
synchronized (this) {
if (fac == null) {
fac = new Factory();
}
}
return fac;
}
public RequestZq getRequest(String req){
return new RequestZq(req);
}
}
Factory类
public class Factory {
private static Factory fac = null;
private Factory() {
}
public Factory getInstance() {
synchronized (this) {
if (fac == null) {
fac = new Factory();
}
}
return fac;
}
public RequestZq getRequest(String req){
return new RequestZq(req);
}
}