Java编写的简单的Web服务器

本文详细介绍了HTTP协议的工作流程及Web服务器的基本功能实现。包括浏览器如何通过DNS解析服务器地址、建立TCP连接并发送HTTP请求,以及服务器如何响应这些请求。同时提供了一个简单的Web服务器程序示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)超文本传输协议Http 的操作过程原理
从协议执行的过程来说,浏览器要访问WWW服务时,首先要完成对WWW服务器的域名的解析。一旦获得了IP地址,浏览器通过TCP向服务器请求建立连接。
每一个万维网站点都有一个服务器进程,不断的监听TCP的80端口(默认),当监听到连接请求后,便与浏览器建立连接。TCP连接建立后,浏览器就向服务器发送获取某一web页面的Http请求。服务器收到HTTP请求后,将构建所请求的web页面所必须的信息,并通过HTTP相应返回给浏览器。浏览器再将信息解析,然后将web页面显示给用户,最后,TCP连接释放。
(二)用户单击一个链接后所发生的事件按顺序如下:
1.浏览器分析链接所指向页面的URL(如 http://write.blog.youkuaiyun.com/mdeditor)。
2浏览器像DNS请求解析(write.blog.youkuaiyun.com)的IP地址。
3.域名系统解析出(write.blog.youkuaiyun.com)服务器的IP地址
4.浏览器与该服务器建立TCP链接(默认端口号80)
5.浏览器发出HTTP请求:GET/mdeditor.
6.服务器通过HTTP相应将mdeditor发送给浏览器。
7.TCP释放链接
8浏览器将mdeditor进行解析,并将web页显示给用户
(三)程序功能:
Web 服务器功能为:
(1) Web 服务器可以接受任何 Web 客户的连接
(2) Web 浏览器客户通过地址栏指定服务器地址和请求的页面
(3) Web 服务器对请求进行处理,发送 HTTP 响应
(4) Web 浏览器客户收到 HTTP 响应后显示页面,关闭连接
(四)程序代码

public class webServer {

    ServerSocket serverSocket = null;
    Socket clientSocket = null; 
    int counter = 1;
    int port = 80 ;
    public void WebConnect() throws IOException{
        serverSocket = new ServerSocket(port);//创建服务器套接字
        System.out.println("Service open....") ;
        while(true){
              clientSocket = serverSocket.accept();//接受客户机连接,生成套接字
              System.out.println("receive "+counter++ +" request" ) ;
              Serverdeal() ;
        }
    }
    public void Serverdeal() throws IOException{
        final String CRLF = "\r\n";
        BufferedReader buf_in = null; //输入流缓冲
        DataOutputStream data_out = null;   //数据输出流
        FileInputStream fileStream=null;//文件输入流
        buf_in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        //socket输出流
        data_out = new DataOutputStream(clientSocket.getOutputStream());

        String headstr = buf_in.readLine();//读取浏览器请求头部第一行

        File file=returnFileByGet(headstr);//分析HTTP得到要回复的文件

        if(file!=null){
            /*****输出HTTP头信息*****/
            //data_out.writeBytes("HTTP/1.0 200 OK" + CRLF);
            if(file.getName().endsWith(".jpg")) {  
            //  data_out.writeBytes("Content-Type: image/jpg" + CRLF);
            }
            if(file.getName().endsWith(".png"))   {
                //将字符串按字节顺序写出到基础输出流中
                data_out.writeBytes("Content-Type: image/png" + CRLF);
            }
            data_out.writeBytes(CRLF);
            try
            {
                //获取回复文件的输入流
                fileStream=new FileInputStream(file);
            } catch (FileNotFoundException e)
            {
                System.out.println("找不到回复文件");
            }   
           if(file.exists()){
               //如果回复文件存在
                byte[] buffer = new byte[1024];//缓冲字节数组,也叫缓冲区
                int bytes = 0;//读到的字节数
                /*发送文件流的实际代码*/
                while ((bytes = fileStream.read(buffer)) != -1) {
                        //不等于-1,就表示还读到内容
                    //将页面文件,写回给浏览器
                    data_out.write(buffer, 0, bytes);
                }
            //完成响应
           }
        }
        if (buf_in != null)buf_in.close();
        if (data_out != null)data_out.close();

        if (fileStream != null)fileStream.close();
    }

public File returnFileByGet(String headstr) {

        File file = null ;
        StringTokenizer headstrTk=null;
        if(headstr!=null){
            headstrTk = new StringTokenizer(headstr);//字符串分割
        }
        //GET命令的格式为:GET 路径/文件名 HTTP/1.1
        //只有为get命令才执行下面的代码
        if (headstrTk.nextToken().equals("GET"))//判断请求方式
        {   
            String rqFName = headstrTk.nextToken();//分割获取请求的文件名
            //如果缺省,返回主页面index.html
            if (rqFName.equals("/"))
            {
                rqFName = "/index.html";
            }
            //获取请求文件,为不为空都要返回文件
            file = new File(rqFName.substring(1));
            //显示请求的GET命令格式 

            System.out.println("request:"+headstr) ; //显示请求
            //显示地址和端口
            System.out.println("User:"+clientSocket.getInetAddress().toString().substring(1) 
                    + "  端口:" + String.valueOf(clientSocket.getPort())) ;
            if (file.exists())//如果找到文件
            {
                //if(file.getName().equals(".html")){
            System.out.println("Find "+rqFName.substring(1)+" it return!") ;                
            }
            else {//如果没找到请求文件,则返回error.html页面
                System.out.println("Not Find "+rqFName.substring(1)+" the Error return!") ; 
                file = new File("error.html");
            }
        }
        return file ;
    }
}

(五)源码下载地址:
(http://download.youkuaiyun.com/download/hdfgo/10189909)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值