• java实现web服务器


    java实现web服务器

    参考:http://jingyan.baidu.com/article/48206aeafba520216ad6b3e0.html

    完整项目代码:http://yunpan.cn/QiJTQAhyIbzKd (提取码:4f0e)

    首先上代码:

      1 /**
      2  * @author hewenwu
      3  * 功能:模拟web服务程序
      4  * 原理:java多线程、socket编程,TCP协议 
      5  */
      6 
      7 import java.io.*;
      8 import java.net.*;
      9 
     10 public class web_server{
     11 
     12     public static void main(String args[]) {
     13 
     14         int client_id = 1;    //初始化客户端id为1,client_id唯一标识一个socket和与其对应的一个java线程
     15      
     16         int PORT = 5000;      //该服务程序监听的端口
     17     
     18         ServerSocket server=null;    //服务端的serversocket
     19     
     20         Socket client=null;          //客户端socket
     21 
     22         try{
     23             server=new ServerSocket(PORT);     //实例化serverclient对象,监听5000端口。一个web服务器只需要一个serversocket
     24 
     25             System.out.println("Web Server is listening on port:"+server.getLocalPort());
     26             
     27             /*这里用到了一个无穷循环,让serversocket始终报纸监听,随时接受客户端程序的请求*/
     28             while(true) {
     29 
     30                 client=server.accept(); //接受客户机的连接请求
     31 
     32                 new ConnectionThread(client,client_id).start(); //为该client创建服务线程
     33 
     34                 client_id++;//客户端标识加1
     35             }
     36             
     37         }catch(Exception e) {    
     38             
     39             System.out.println(e);    
     40         }                   
     41     }      
     42 }
     43 
     44 
     45 
     46 /* 继承子Thread类,ConnnectionThread类完成与一个Web浏览器的通信 */
     47 
     48 class ConnectionThread extends Thread {
     49 
     50     public Socket client = null; // 连接Web浏览器的socket字
     51 
     52     public int counter = 0; // 计数器
     53 
     54     public ConnectionThread(Socket cl , int c) {
     55         
     56         client=cl;
     57         counter=c;
     58     }
     59 
     60 @SuppressWarnings("deprecation")
     61 
     62 public void run()
     63 {
     64     try{
     65         
     66         String destIP=client.getInetAddress().toString(); // 客户机IP地址
     67 
     68         int destport=client.getPort(); // 客户机端口号
     69 
     70         System.out.println("Connection "+counter+":connected to "+destIP+" on port "+destport+".");
     71 
     72         PrintStream outstream=new PrintStream(client.getOutputStream());//获取与客户机的打印输出流
     73 
     74         DataInputStream instream=new DataInputStream(client.getInputStream());//获取从客户机的数据输入流
     75 
     76         String inline=instream.readLine(); // 读取Web浏览器提交的请求信息
     77 
     78         System.out.println("Received:"+inline);
     79 
     80         if (get_request_type(inline)) { // 如果是GET请求
     81 
     82             String filename=get_file_name(inline);
     83 
     84             File file=new File(filename);
     85 
     86             if (file.exists()) { // 若文件存在,则将文件送给Web浏览器
     87 
     88                 System.out.println(filename+" requested.");
     89 
     90                 //发送HTML的head信息
     91                 
     92                 outstream.println("HTTP/1.0 200 OK");
     93 
     94                 outstream.println("MIME_version:1.0");
     95 
     96                 outstream.println("Content_Type:text/html");
     97 
     98                 int len=(int)file.length();
     99 
    100                 outstream.println("Content_Length:"+len);
    101 
    102                 outstream.println("");
    103 
    104                 //发送HTML正文信息
    105                 sendfile(outstream,file); // 发送文件
    106 
    107                 //清空输出流
    108                 outstream.flush();
    109   
    110             } else { // 文件不存在时
    111 
    112                 String filenam="error.html";
    113 
    114                 //得到错误信息页面
    115                 File file1=new File(filenam);
    116 
    117                 System.out.println(filename+" requested.");
    118 
    119                 //输出HTML的头信息
    120                 outstream.println("HTTP/1.0 200 OK");
    121 
    122                 outstream.println("MIME_version:1.0");
    123 
    124                 outstream.println("Content_Type:text/html");
    125 
    126                 int len=(int)file.length();
    127 
    128                 outstream.println("Content_Length:"+len);
    129 
    130                 outstream.println("");
    131 
    132                 //输出错误信息文件
    133                 sendfile(outstream,file1); // 发送文件
    134 
    135                 //清空缓冲区
    136                 outstream.flush();
    137             }
    138         }
    139 
    140         //设置延时,等待文件传送完毕
    141         long m1=1; 
    142         while (m1<11100000) 
    143         {
    144             m1++;
    145             
    146         } 
    147         
    148         //关闭客户端socket
    149         client.close();
    150    
    151     }catch(IOException e) {
    152 
    153         System.out.println("Exception:"+e);
    154     }
    155 }
    156 
    157 
    158 /* 获取请求类型是否为“GET” */
    159 
    160 boolean get_request_type(String s) { 
    161 
    162     if (s.length()>0)
    163 
    164     {
    165         if(s.substring(0,3).equalsIgnoreCase("GET")) 
    166 
    167             return true;
    168     }
    169     
    170     return false;
    171 }
    172 
    173 /* 获取要访问的文件名 */
    174 
    175 String get_file_name(String s) {
    176 
    177     /*get请求的第一行信息格式为:“GET /books/?name=Professional%20Ajax HTTP/1.1” 
    178       String.substring(int i)方法是从第i个字符开始取,取出后面所有的字符
    179       String.substring(int begin,int end)方法是取出从begin到end的所有字符
    180       */
    181     
    182     String file_name = s.substring(s.indexOf(' ')+1);//这一条是把get后面所有的字符串取出来
    183 
    184     file_name = file_name.substring(0,file_name.indexOf(' '));
    185 
    186     try{
    187 
    188         if(file_name.charAt(0)=='/')
    189 
    190             file_name=file_name.substring(1);
    191 
    192     }catch(StringIndexOutOfBoundsException e) {
    193 
    194         System.out.println("Exception:"+e);
    195     }
    196 
    197     if (file_name.equals("")) {
    198         
    199         file_name="index.html";
    200     }
    201 
    202     return file_name;
    203 }
    204 
    205 /*把指定文件发送给Web浏览器 */ 
    206 
    207 void sendfile(PrintStream outs,File file){
    208 
    209     try{
    210 
    211         DataInputStream in=new DataInputStream(new FileInputStream(file));
    212 
    213         int len=(int)file.length();
    214 
    215         byte buf[]=new byte[len];
    216 
    217         in.readFully(buf);
    218 
    219         outs.write(buf,0,len);
    220 
    221         outs.flush();
    222 
    223         in.close();
    224 
    225     }catch(Exception e){
    226 
    227         System.out.println("Error retrieving file.");
    228 
    229         System.exit(1);
    230         
    231     }
    232 }
    233 }


    web_server原理解析:

        该程序用到的2个最基本的技术:1、java多线程技术,比较简单;2、socket编程技术。

        1、java多线程技术:每次当浏览器请求该服务器发送数据的时候,服务器都为这个请求新建一个线程(new Thread()),所有的线程独立工作,因此一个web server能同时接受多个client的请求。(详细的多线程技术参见其他文章)

        2、socket技术:socket分为ServerSocket和一般的Socket。web服务器中,必须要有一个ServerSocket对象,在新建ServerSocket对象时,要为其指定一个监听端口:

    new ServerSocket(5000);

        然后用一个无穷循环来循环检测该端口有没有请求:

        while(true) {
     

                     client=server.accept(); //接受客户机的连接请求
      
                     new ConnectionThread(client,client_id).start(); //为该client创建服务线程
     
                     client_id++;//客户端标识加1
                }

        当该端口接收到请求的时候,ServerSocket对象便接受该请求,并为该请求创建一个socket对象,该socket对象便可以与客户端的socket对象之间交换数据,数据交换是基于TCP协议的。

        流程图:

    至于其他的数据流操作,可以参考其他资料,数据java基本操作。

    完整的项目运行方案:

    1、在Eclipse里新建java项目,添加一个类web_server.class,将上面的代码复制进去,保存。

    2、用记事本写两个HTML文件index.html和error.html,保存。

    3、要运行该web server有2种方法:用Eclipse或者用dos命令:

    用Eclipse:用Eclipse需要将index.html和error.html文件放入到项目文件夹与src同级的文件夹下,并且刷新Eclipse里面的项目:

    运行该项目,即可。

    用dos命令:首先用javac命令编译web_server.java文件,得到web_server.class和ConnectionThread.class文件,将web_server.class、ConnectionThread.class、index.html和error.html文件放入同一个文件夹,然后用java web_server运行改程序即可。

    浏览器访问:在地址栏输入:

    http://localhost:5000/index.html,回车,可以看到访问成功:

    输入:http://localhost:5000/index1.html,回车,由于没有index1.html文件,所以访问失败:

  • 相关阅读:
    inner join ,left join ,right join 以及java时间转换
    华为机试-整形数组合并
    华为机试-公共字串计算
    两个字符串的最长公共子序列的长度
    华为机试-字符串通配符
    工作中总结的编程小技巧
    C语言高效编程的几招(绝对实用,绝对经典)
    Java float保留两位小数或多位小数
    新浪云、阿里云、百度云、谷歌云、亚马逊云
    java经典40+分析
  • 原文地址:https://www.cnblogs.com/hewenwu/p/3710344.html
Copyright © 2020-2023  润新知