利用java构建http服务器

Posted on 2009-12-17 17:26 terryxue 阅读(2036) 评论(3)  编辑  收藏 所属分类: java

web服务器大家都会用,可是它的实现原理是到底如何呢,其实只要读一下http协议,大家基本也能开发出一个简单的web服务器出来了。

web请求分为如下几步

1. 浏览器向服务建立TCP/IP连接,Java中通过java.net.Socket实现

2. Web浏览器向Web服务器发送请求命令。通过Socket的输出流向服务器写如下信息:

  GET /uri HTTP/1.1,很显示第一部分为请求的方法,第二部分为请求的URI,第三部分为请求的协议

3. Web浏览器发送请求头信息。这部分包括浏览器的版本信息,接受的格式、编码等,还有非常有用的一个数据Cookie也是在这里发送的。

4. 头信息发送完后,发送一个空格表示结束,如果是post请求,则继续发送Post正文。

5. Web服务器做出应答,如返回"HTTP/1.1 200  OK",表示请求成功,或者返回404,500等状态信息表示找不到页面或服务器错误。

6. Web服务器发送应答头信息,这部分表示了返回的内容类型(如是gif还是exe还是html等),返回的数据的编码,长度,当然还有Cookie(通过set-Cookie来发送)

7. 在发送完应答头后,则发送一个空行。如果有响应正文,则在后面继续发送响应内容。

8. 关闭TCP/IP连接

以下代码简单的模拟了这一过程。

客户端代码:

//1. 建立到服务器的连接
private void connect() throws Exception{
  socket 
= new Socket("serverName"80);        
}

//2. 发送请求命令
private void sendRequestCommand() throws Exception{
  OutputStream os 
= socket.getOutputStream();
  os.write(
"GET /index.html HTTP/1.1\n".getBytes());
}

//3. 发送请求头信息
private void sendHeader() throws Exception{
  OutputStream os 
= socket.getOutputStream();
  os.write((
"Accept: */*\n" +
    
"Accept-Language: zh-cn;q=0.5\n" +
    
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; CIBA; .NET CLR 2.0.50727)\n" +
    
"Host: 192.168.1.110\n" +
    
"Connection: Keep-Alive\n" +
    
"\n").getBytes());
  os.flush();
}

//4. 检测服务器发送回来的响应
private void getResponse() throws Exception{
  InputStream is 
= socket.getInputStream();
  
while(is.available() == 0){
    Thread.sleep(
10);
  }

  BufferedReader br 
= new BufferedReader(new 
    InputStreamReader(is, 
"utf-8"));
  String line 
= null;
  
while((line = br.readLine()) != null{
    System.out.println(line);
  }

}

服务器代码如下:
private ServerSocket server;    
    
public void start() throws Exception{
        server 
= new ServerSocket(80);//监听80端口        
        accept();
    }

    
    
private void accept(){
        
new Thread(){
            
public void run(){
                
while(true){
                    
try {
                        System.out.println(
"accept");
                        Socket socket 
= server.accept();
                        System.out.println(
"new client.");
                        processRequest(socket);
                    }
 catch (IOException e) {
                        e.printStackTrace();
                    }

                }

            }

        }
.start();
    }

    
    
private void processRequest(Socket socket){
        
new RequestProcessor(socket).start();
    }

    
//将每个请求用一个单独的线程来进行处理,这样可以实现多个请求的并发处理功能
    private class RequestProcessor extends Thread{
        Socket socket;
        RequestProcessor(Socket socket)
{
            
this.socket = socket;
        }

        
public void run(){
            
try {
                InputStream is 
= socket.getInputStream();
                
while(is.available() == 0){
                    Thread.sleep(
10); //检测客户端是否发送过来了请求数据
                }

                
                
while(is.available() > 0){
                    System.out.print((
char)is.read());//打印发送过来的所有数据,可以保存起来以做进一步的处理
                }

                
                
                String info 
= "HTTP/1.1 200 OK\n" +
                        
"Server: Apache-Coyote/1.1\n" +
                        
"Content-Type: text/html;charset=utf-8\n" +
                        
"Content-Length: 1021\n" +
                        
"Date: Wed, 09 Dec 2009 05:00:27 GMT\n" +
                        
"\n";                
                OutputStream os 
= socket.getOutputStream();
                os.write(info.getBytes(
"utf-8"));
                os.flush();
                
                FileInputStream fis 
= new FileInputStream("webRoot/index.html");//假设用户请求的是index.html,读取该文件做为响应
                byte data[] = new byte[1024*10];
                
int length = 0;
                
while((length = fis.read(data)) > 0){
                    os.write(data, 
0, length);
                }
                
                os.flush();
                os.close();
            }
 catch (Exception e) {
                
// TODO Auto-generated catch block
                e.printStackTrace();
            }

            
        }

    }

Feedback

# re: 利用java构建http服务器  回复  更多评论   

2009-12-17 18:13 by simaliu
呵呵
我也做过这方面的工作
有兴趣可以交流一下

# re: 利用java构建http服务器  回复  更多评论   

2009-12-18 08:35 by mathfox
这也能上主页?

# re: 利用java构建http服务器  回复  更多评论   

2009-12-18 08:36 by mathfox
如果你想做web 服务器,

请搜索how tomcat works,虽然讲的是比较老的tomcat,不过还是很有参考价值的。

我以后我仔细看看

只有注册用户登录后才能发表评论。


网站导航:
 

posts - 9, comments - 24, trackbacks - 0, articles - 0

Copyright © terryxue