无线&移动互联网技术研发

换位思考·····
posts - 19, comments - 53, trackbacks - 0, articles - 283
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

利用java构建http服务器(摘)

Posted on 2009-12-27 00:12 Gavin.lee 阅读(417) 评论(0)  编辑  收藏 所属分类: java SE & EE

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连接

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

客户端代码:

package com.yixun.wap;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    Socket socket 
= null;
    
    
// 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);
        }

    }

}


服务器代码如下:
package com.yixun.wap;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    
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) {
                e.printStackTrace();
            }


        }

    }

}



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


网站导航: