一个简单的http服务器(Java)

测试方法:

运行后打开IE,输入http://localhost/xxx.htm,其中xxx.htm是你放在e:\webroot\中的同名文件,

例如,在e:\webroot\目录下有clotho.htm,可以访问http://localhost/clotho.htm来浏览.

另外,如果程序不是使用默认的80端口,可以在localhost后面加端口号,

例如,代码改成HttpServer.port = 8086,可以访问http://localhost:8086/clotho.htm来浏览.

 

代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.Date;

public class HttpServer implements Runnable {
    
public static void main(String args[]) {
        HttpServer.root 
= "e:\\webroot\\"// 服务器根目录
        HttpServer.port = 80// 浏览器默认请求80端口
        HttpServer.listen();
    }

    
public static void listen() {
        ServerSocket serverSocket 
= null;
        
try {
            serverSocket 
= new ServerSocket(port);
            
while (true) {
                Socket socket 
= serverSocket.accept();
                HttpServer server 
= new HttpServer(socket);
                Thread thread 
= new Thread(server);
                thread.start();
            }
        } 
catch (Exception ex) {
            ex.printStackTrace();
        } 
finally {
            
try {

            } 
catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    
/**
     * 服务器根目录
     
*/
    
public static String root;

    
/**
     * 端口
     
*/
    
public static int port;

    
/**
     * 单个请求的套接字
     
*/
    
private Socket socket;

    
public HttpServer(Socket socket) {
        
this.socket = socket;
    }

    
public void run() {
        
try {
            
// 获取请求信息
            InputStream is = socket.getInputStream();
            InputStreamReader isr 
= new InputStreamReader(is);
            BufferedReader br 
= new BufferedReader(isr);

            
// 生成响应数据
            String filename = getRequestFilename(br);
            String contentType 
= getContentType(filename);
            FileInputStream fis 
= new FileInputStream(root + filename);
            BufferedInputStream bis 
= new BufferedInputStream(fis);
            
int length = bis.available();
            String respText 
= getResponseText(length, contentType);

            
// 响应请求的浏览器
            OutputStream os = socket.getOutputStream();
            BufferedOutputStream bos 
= new BufferedOutputStream(os);
            bos.write(respText.getBytes()); 
// 返回http header信息

            
byte buffer[] = new byte[length];
            bis.read(buffer, 
0, length);
            bos.write(buffer); 
// 返回文件数据
            bos.flush();
            bos.close();

            br.close();
        } 
catch (Exception ex) {
            ex.printStackTrace();
        } 
finally {
            
try {
                socket.close();
            } 
catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    
/**
     * 解析请求的页面文件名
     
*/
    
private String getRequestFilename(BufferedReader br) {
        String filename 
= null;
        String line 
= null;
        
try {
            
while ((line = br.readLine()) != null) {
                
if (line.startsWith("GET")) {
                    String[] segments 
= line.split(" ");
                    filename 
= segments[1];
                }
                
if (line.length() == 0 || line.equals("\n")) {
                    
break;
                }
            }
        } 
catch (Exception ex) {
            ex.printStackTrace();
        }
        
return filename;
    }

    
/**
     * ContentType属性指定响应的http内容类型
     
*/
    
private String getContentType(String filename) {
        
int pos = filename.lastIndexOf('.');
        String ext 
= filename.substring(pos + 1).toLowerCase();
        String contentType 
= null;
        
switch (ext.charAt(0)) {
        
case 'h'// htm html
            contentType = "text/html";
        
case 'j'// jpg
            contentType = "image/jpg";
        
case 'g'// gif
            contentType = "image/gif";
        
default:
            contentType 
= "*/" + ext;
        }
        
return contentType;
    }

    
/**
     * 生成响应的http header信息
     
*/
    
private String getResponseText(int length, String contentType) {
        StringBuilder sb 
= new StringBuilder();
        sb.append(
"HTTP/1.1 200 OK\n");
        sb.append(
"Date: " + new Date() + "\n");
        sb.append(
"Server: Clotho\n");
        sb.append(
"Accept-Ranges: bytes\n");
        sb.append(
"Content-Length: " + length + "\n");
        sb.append(
"Keep-Alive: true\n");
        sb.append(
"Connection: Keep-Alive\n");
        sb.append(
"Content-Type: " + contentType + "\n");
        sb.append(
"\n");
        
return sb.toString();
    }
}

 

 

posted @ 2010-02-04 16:45  Clotho_Lee  阅读(1500)  评论(0)    收藏  举报