以下代码是我自己写的第一个Web服务器。它支持纯文本的英文字符的静态HTML页面。复制并将代码编译成.class文件后,运行它即可。它的监听端口是6789,网站根目录为C:\Inetpub,如果该目录下有一个test.html文件,那么,运行它后,在浏览器中输入:
http://localhost:6789/test.html,即可实现访问。
它还可以作为一个查看浏览器请求报文(HTTP请求报文)的工具,要实现这点,只需要在浏览器中输入一个并不存在的网页文件(如 http://localhost:6789/notexists.html),服务器程序便把客户端浏览器的请求报文回显出来。
源代码如下:
import java.io.*;
import java.net.*;
public class MyWebServer {
public static String WebRoot = "C:\\Inetpub";
/**
* 将虚拟路径转换成实际物理路径
* @param virtualPath
* @return
* @throws Exception
*/
private static String mapPath(String virtualPath) throws Exception {
return WebRoot + virtualPath.replace("/", "\\");
}
private static String parseVirtualPathFromRequest(String request) throws Exception {
return request.substring(4, request.indexOf(" HTTP/1.1"));
}
public static void main(String argv[]) throws Exception {
// 客户端来的请求字符串
String request;
String requestLine;
// 响应字符串
String response;
// HTML 模板
String htmlTemplate = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title></title></head><body></body></html>";
long count;
// 显示启动信息
printInfo("我的网页服务器启动了。");
// 定义端口值
int portNo;
portNo = 6789;
// 定义欢迎套接字
ServerSocket welcomeSocket = new ServerSocket(portNo);
// 输入信息
printInfo("我的网页服务器在端口 " + portNo + " 处开启了一个欢迎套接字。");
// 不断接收来自客户端的请求
count = 0L;
while (true) {
// 建立新的连接套接字
Socket connectionSocket = welcomeSocket.accept();
if (connectionSocket != null) {
printInfo("我的网页服务器收到来自客户端的请求,连接套接字已经建立。");
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
request = "";
response = "";
requestLine = "";
while (true) {
try {
printInfo("我的网页服务器开始读入客户端的请求字符串……");
requestLine = inFromClient.readLine();
if (! requestLine.equals("")) {
request += requestLine + "\n";
printInfo("客户端请求:" + requestLine);
if (request.contains("quit") || request.contains("exit")) {
printInfo("客户端请求退出。");
}
if (request.contains("quit") || request.contains("exit")) {
break;
}
} else {
printInfo("客户端请求为空。我的网页服务器准备关闭该TCP连接。");
// 关闭连接前,给予一个响应
String filePath = mapPath(parseVirtualPathFromRequest(request));
File file = new File(filePath);
if (file.exists()) {
FileReader myFile = new FileReader(filePath);
BufferedReader myReader = new BufferedReader(myFile);
String fileStream = myReader.readLine();
while (fileStream != null) {
response += fileStream + "\n";
fileStream = myReader.readLine();
}
myReader.close();
myFile.close();
} else {
response = htmlTemplate.replace("<title></title>", "<title>Response Frome MyWebServer</title>").replace("<body></body>", "<body><h1>Echo your request: </h1><pre>" + request + "</pre><p>You request " + filePath + ", which is not exists.</p></body>");
}
outToClient.writeBytes(response);
printInfo("我的网页服务器响应: " + response);
connectionSocket.close();
break;
}
} catch (Exception e) {
response = "退出" + "\n";
printInfo("连接断开了,可能是客户端离开。详细信息为:\n" + e.toString());
break;
} finally {
}
}
printInfo("连接关闭了。");
inFromClient.close();
outToClient.close();
} else {
printInfo("我的网页服务器收到来自客户端的请求,但是连接套接字未能建立。");
}
connectionSocket.close();
}
}
/**
* 在控制板中输入信息
* @param info
* @throws Exception
*/
private static void printInfo(String info) throws Exception {
System.out.println(info);
}
}