(探索)用Java Socket模拟Web服务器的功能I

先看效果再看代码

(探索)用Java Socket模拟Web服务器的功能I

如果键入的地址在服务器找不到的话,就会显示默认的FileNotFound.html页面

(探索)用Java Socket模拟Web服务器的功能I

更多精彩图片请看写一篇文章“(探索)用Java Socket模拟Web服务器的功能II”

HTTPServer.java

package org.bruce.httpserver.version1; import java.net.ServerSocket; import java.net.Socket; public class HTTPServer { String serverName; String Version; int serverPort; public HTTPServer(String name, String version, int port) { this.serverName = name; this.Version = version; this.serverPort = port; } //构造一个server, 并运行 public static void main(String[] args) { HTTPServer server = new HTTPServer("HTTPServer", "1.0", 80); server.run(); } public void run() { //显示名字和版本号 System.out.println(serverName+" version: "+Version); System.out.println(); System.out.println(); try { //得到服务监听端口 ServerSocket ss = getServerSocket(); while(true) { //等待连接请求 Socket s = ss.accept(); //为连接请求分配一个线程 (new HTTPServerThread(s)).start(); } } catch(Exception e) { e.printStackTrace(); System.exit(1); } } //一句代码,其实和上面写在一起就行了! ServerSocket getServerSocket() throws Exception { return new ServerSocket(serverPort); } }

HTTPServerThread.java

package org.bruce.httpserver.version1; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.Socket; public class HTTPServerThread extends Thread { Socket client; //构造方法 public HTTPServerThread(Socket client) { this.client = client; } public void run() { try { this.describeConnectionInfo(client); BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream()); //HTTPInputStream 是自定义的过滤流 HTTPInputStream httpis = new HTTPInputStream(client.getInputStream()); //得到请求头 HTTPRequest request = httpis.getRequest(); //显示头信息 request.log(); //System.out.println("*********** 头信息显示完毕 **************"); //只处理GET请求 if(request.isGetRequest()) { processGetRequest(request, bos); } System.out.println("Request completed. Closing connection."); //以示区分 System.out.println("=============================================================="); //非持久性 client.close(); } catch(IOException e) { System.out.println("IOException orccurred!"); e.printStackTrace(); } } //陈列当前连接的相关信息 void describeConnectionInfo(Socket client) { //服务器主机名 String destName = client.getInetAddress().getHostName(); //服务端IP地址 String destAddr = client.getInetAddress().getHostAddress(); //服务端端口 int destPort = client.getPort(); //打印信息 System.out.println("Accept connection to "+destName+"("+destAddr+")" +" on port "+ destPort + "."); } void processGetRequest(HTTPRequest request, BufferedOutputStream bos) throws IOException { String fileName = request.getFileName(); //System.out.println("********** 抽象路径名:" + fileName + " ***************"); File file = new File(fileName); // 下发客户端所请求的文件 if(file.exists()) { sendFile(bos, file); } else { // getCanonicalPath(): 返回抽象路径名的规范路径名字符串。 System.out.println("File " + file.getCanonicalPath() + " does not exist."); sendFile(bos, new File("WebRoot/FileNotFound.htm")); } } void sendFile(BufferedOutputStream bos, File file) { try { //①将客户端所请求的文件读入到程序中来,并完整地放入为其开辟的内存空间 buffer 中 DataInputStream dis = new DataInputStream(new FileInputStream(file)); //file.length()的返回值为 long 型! int len = (int)file.length(); byte[] buffer = new byte[len]; dis.readFully(buffer); dis.close(); //②将读入到程序中的文件写出去发给客户端 bos.write(("Http/1.0 200 OK/r/n").getBytes()); bos.write(("Content-Length: " + buffer.length + "/r/n").getBytes()); bos.write(("Content-Type: text/HTML/r/n/r/n").getBytes()); bos.write(buffer); bos.flush(); bos.close(); //③在控制台输出相应的信息 //System.out.println("********** 绝对路径名:" + file.getCanonicalPath() + " ***************"); System.out.println("File sent: " + file.getCanonicalPath()); System.out.println("Number of bytes: " + len); } catch(Exception e) { try { bos.write(("HTTP/1.0 400 " + "No can do" + "/r/n").getBytes()); bos.write(("Content-Type: text/HTML/r/n/r/n").getBytes()); } catch(Exception e1) { e1.printStackTrace(); } System.out.println("Error retrieving "+ file); } } }