自己做的簡單的web服務器

我最近修的電子商務概論的課程,老師佈置的作業,是要做個簡單的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端口

服務器名字裏面有我的名字,呵呵,在代碼裏,比較隱蔽,不過牛哥哥們一定會識破的,呵呵

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章