<p>以下代码是我自己写的第一个Web服务器。它支持纯文本的英文字符的静态HTML页面。复制并将代码编译成.class文件后,运行它即可。它的监听端口是6789,网站根目录为C:\Inetpub,如果该目录下有一个test.html文件,那么,运行它后,在浏览器中输入:</p>
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); }
}