`
yujiawei
  • 浏览: 60173 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

简单的web服务器

    博客分类:
  • JAVA
阅读更多

Server.java
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.java
package cn.tuoxie007.webserver;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

/**
 * string util fetch content from a stream thought about charset,
 * or codec a bytes and so on
 * @author xuke
 * <br/>
 *  <a href="http://tuoxie007.cn">welcome to autor's home page</a>
 * 
 */
public class StringUtil {

	public static final int READ_BUFFER = 10240;

	
	/**
	 * merge the list of byte array to a singal byte array
	 * @param bufList
	 * @return
	 */
	public static byte[] getBytesFromByteList(List<byte[]> bufList){
		int size = 0;
		for(int i=0; i<bufList.size(); i++){
			size += bufList.get(i).length;
		}
		byte[] bytes = new byte[size];
		int off = 0;
		for (int i = 0; i < bufList.size(); i++) {
			byte[] b = bufList.get(i);
			for (int j = 0; j < b.length; j++) {
				bytes[off++] = b[j];
			}
		}
		return bytes;
	}
	
	
	/**
	 * read content of stream as list of byte array
	 * @see cn.edu.hust.search.spider.loader.StringUtil#getBytesFromStream(InputStream)
	 * @param is
	 * @return
	 * @throws IOException
	 */
	public static List<byte[]> getListFromStream(InputStream is) throws IOException{
		DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
		int read = 0;
		List<byte[]> bufList = new LinkedList<byte[]>();
		byte[] buf = new byte[READ_BUFFER];

		while (true) {
			int len = dis.read(buf, read, READ_BUFFER - read);
			if (len == -1) {
				byte[] buff = new byte[read];
				for(int i=0; i<read; i++){
					buff[i] = buf[i];
				}
				bufList.add(buf);
				break;
			}
			read += len;
			if (read == READ_BUFFER) {
				bufList.add(buf);
				buf = new byte[READ_BUFFER];
				read = 0;
			}
		}
		return bufList;
	}

	/**
	 * read content of stream as byte array
	 * @see cn.edu.hust.search.spider.loader.StringUtil#getListFromStream(InputStream)
	 * @param is
	 * @return
	 * @throws IOException
	 */
	public static byte[] getBytesFromStream(InputStream is) throws IOException {
		DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
		int read = 0;
		List<byte[]> bufList = new LinkedList<byte[]>();
		byte[] buf = new byte[READ_BUFFER];

		while (true) {
			int len = dis.read(buf, read, READ_BUFFER - read);
			if (len == -1) {
				bufList.add(buf);
				break;
			}
			read += len;
			if (read == READ_BUFFER) {
				bufList.add(buf);
				buf = new byte[READ_BUFFER];
				read = 0;
			}
		}
		byte[] bytes = new byte[bufList.size() > 1 ? bufList.size() * READ_BUFFER
				+ read : read];
		int off = 0;
		for (int i = 0; i < bufList.size(); i++) {
			byte[] b = bufList.get(i);
			int len = Math.min(bytes.length - i * READ_BUFFER, READ_BUFFER);
			for (int j = 0; j < len; j++) {
				bytes[off++] = b[j];
			}
		}
		return bytes;
	}
	
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics