我最近修的电子商务概论的课程,老师布置的作业,是要做个简单的web服务器
我做了一个,还拿去给同学当做软件课设给交了
我在里面挂了一个静态的网站,运行的还比较稳定
不过没有做多线程,也没有处理很多的mime类型
比较小,总共就一百多行,呵呵
package cn.tuoxie007.webserver; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; public class Server { private boolean run = true; public Server(int port) { //start server try { ServerSocket ss = new ServerSocket(port); while (run) { //get a client Socket s = ss.accept(); //invoke a method to response this request response(s); } } catch (IOException e) { System.err.println("server eroor :" + e.getMessage()); } } byte[] readFile(File f){ try { return StringUtil.getBytesFromStream(new FileInputStream(f)); } catch (FileNotFoundException e) { try { return StringUtil.getBytesFromStream(new FileInputStream("www/404.html")); } catch (FileNotFoundException e1) { } catch (IOException e1) { } } catch (IOException e) { } return new byte[0]; } int getFileLength(File f){ return readFile(f).length; } static byte[] FILE_NOT_FOUND_HEAD = "HTTP/1.1 404 Not Found\n".getBytes(); static byte[] REPONSE_OK = "HTTP/1.1 200 OK\n".getBytes(); static byte[] CSS_CONTENT_TYPE = "Content-Type: text/css; charset=UTF-8\n".getBytes(); static byte[] JAVASCRIPT_CONTENT_TYPE = "Content-Type: text/javascript; charset=UTF-8\n".getBytes(); static byte[] HTML_CONTENT_TYPE = "Content-Type: text/html; charset=UTF-8\n".getBytes(); static byte[] JPEG_CONTENT_TYPE = "Content-Type: image/jpeg\n".getBytes(); static byte[] GIF_CONTENT_TYPE = "Content-Type: image/gif\n".getBytes(); static byte[] IMPORTANT_DATA = new byte[]{ 83, 101, 114, 118, 101, 114, 58, 32, 115, 105, 109, 112, 108, 101, 32, 115, 116, 97, 116, 105, 99, 32, 119, 101, 98, 32, 115, 101, 114, 118, 101, 114, 32, 98, 121, 32, 116, 117, 111, 120, 105, 101, 48, 48, 55, 10}; /** * response client * @param s */ private void response(Socket s) { try { BufferedReader br = new BufferedReader(new InputStreamReader(s .getInputStream())); String firstLine = br.readLine(); if (firstLine.startsWith("GET") && firstLine.contains("HTTP/")) { String[] parts = firstLine.split("\\s+"); if (parts.length > 1) { String requestFile = parts[1]; File f = getFile(requestFile); OutputStream out = s.getOutputStream(); if(!f.exists()){// file not found out.write(FILE_NOT_FOUND_HEAD); } // file found // write response head for different file formats String fileName = f.getName(); out.write(REPONSE_OK); out.write(IMPORTANT_DATA); out.write(("Content-Length: " + getFileLength(f) + "\n").getBytes()); if(fileName.endsWith("css")){ out.write(CSS_CONTENT_TYPE); }else if(fileName.endsWith("js")){ out.write(JAVASCRIPT_CONTENT_TYPE); }else if(fileName.endsWith("jpg")){ out.write("Accept-Ranges: bytes\n".getBytes()); out.write(JPEG_CONTENT_TYPE); }else if(fileName.endsWith("gif")){ out.write("Accept-Ranges: bytes\n".getBytes()); out.write(GIF_CONTENT_TYPE); }else{ out.write(REPONSE_OK); out.write(HTML_CONTENT_TYPE); } out.write("\n".getBytes());// for firefox, for ie this line is not need // write response body out.write(readFile(f)); // log this request log(s.getInetAddress().getHostAddress(), f.getAbsolutePath().split("www")[1]); } } } catch (IOException e) { }finally{ if(s != null){ try { s.close(); } catch (IOException e) { } } } } private void log(String ip, String file) { // TODO you can record this request here // write this message to disk yourself okay? I just print them System.out.println("[INFO] " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + ", client:" + ip + ", request file:" + file); } /** * get local file * @param file * @return * @author xuke */ private File getFile(String file) { if(file.equals("/")){ file += "index.html"; }else{ String[] parts = file.split("/"); String endFile = parts[parts.length-1]; if(endFile.endsWith("/")){ file += "index.html"; }else if(!endFile.contains(".")){ file += "/index.html"; } } return new File(new File("www"), file); } /** * close server * @author xuke */ public void shutdown() { this.run = false; } /** * Main * @param args */ public static void main(String[] args) { new Server(80); } }
还有个类StringUtil,是我常用的一个工具类的一部分
有兴趣的话可以整个下过去看看, 运行上面贴出来的这个类就启动了,在80端口
服务器名字里面有我的名字,呵呵,在代码里,比较隐蔽,不过牛哥哥们一定会识破的,呵呵