web服务器,用于理解 http协议

Java代码 复制代码
  1. /**  
  2.  * 用Java语言实现HTTP服务器,首先启动一个java.net.ServerSocket在提供服务的端口上监听连接.向客户返回文本时,可以用  
  3.  * PrintWriter,但是如果返回二进制数据,则必须使用OutputStream.write(byte[])方法,返回的应答消息字符串可以使用  
  4.  * String.getBytes()方法转换为字节数组返回,或者使用PrintStream的print()方法写入文本,用  
  5.  * write(byte[])方法写入二进制数据.  
  6.  *   
  7.  * 以工程所在目录为web的根目录。 在工程的根目录下放一个大概如下的index.html  
  8.  *   
  9.  * <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  
  10.  * "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta  
  11.  * http-equiv="Content-Type" content="text/html; charset=gbk">  
  12.  * <title>简单的测试</title> </head> <body> 你好!这是一个 简单的web服务器。<br>  
  13.  * 这是一个图片!<br>  
  14.  *   
  15.  * <form action="/index.html"> <img alt="" src="images/test.gif"><br>  
  16.  * 姓名:<input type="text" name="name" /><br>  
  17.  * 密码:<input type="password" name="pass"></input><br>  
  18.  * <input type="submit"/> </form> </body> </html>  
  19.  *   
  20.  * 放入图片位置: 工程根目录/images/test.gif <br>  
  21.  * 打开浏览器输入http://localhost/index.html 可以展示index.html  
  22.  *   
  23.  * @author guazi  
  24.  */  
  25. public class SimpleHttpServer implements Runnable {   
  26.        
  27.     ServerSocket serverSocket;// 服务器Socket   
  28.   
  29.        
  30.     /**  
  31.      * 服务器监听端口, 默认为 80.  
  32.      */  
  33.     public static int PORT = 80;// 标准HTTP端口   
  34.   
  35.     /**  
  36.      * 开始服务器 Socket 线程.  
  37.      */  
  38.     public SimpleHttpServer() {   
  39.         try {   
  40.             serverSocket = new ServerSocket(PORT);   
  41.         } catch (Exception e) {   
  42.             System.out.println("无法启动HTTP服务器:" + e.getMessage());   
  43.         }   
  44.         if (serverSocket == null)   
  45.             System.exit(1);// 无法开始服务器   
  46.   
  47.         new Thread(this).start();   
  48.         System.out.println("HTTP服务器正在运行,端口:" + PORT);   
  49.     }   
  50.   
  51.        
  52.     /**  
  53.      * 运行服务器主线程, 监听客户端请求并返回响应.  
  54.      */  
  55.     public void run() {   
  56.         while (true) {   
  57.             try {   
  58.                 Socket client = null;// 客户Socket   
  59.                 client = serverSocket.accept();// 客户机(这里是 IE 等浏览器)已经连接到当前服务器   
  60.                 if (client != null) {   
  61.                     System.out.println("连接到服务器的用户:" + client);   
  62.                     try {   
  63.                         // 第一阶段: 打开输入流   
  64.                         BufferedReader in = new BufferedReader(   
  65.                                 new InputStreamReader(client.getInputStream()));   
  66.   
  67.                         System.out.println("客户端发送的请求信息: ***************");   
  68.                         // 读取第一行, 请求地址   
  69.                         System.out.println("http协议头部信息:");   
  70.                         String line = in.readLine();   
  71.                         System.out.println(line);   
  72.                         String resource = line.substring(line.indexOf('/'),   
  73.                                 line.lastIndexOf('/') - 5);   
  74.                         // 获得请求的资源的地址   
  75.                         resource = URLDecoder.decode(resource, "gbk");// 反编码   
  76.   
  77.                         String method = new StringTokenizer(line).nextElement()   
  78.                                 .toString();// 获取请求方法, GET 或者 POST   
  79.   
  80.                         // 读取浏览器发送过来的请求参数头部信息   
  81.                         while ((line = in.readLine()) != null) {   
  82.                             System.out.println(line);   
  83.   
  84.                             if (line.equals(""))   
  85.                                 break;   
  86.                         }   
  87.   
  88.                         System.out.println("http协议头部结束 ***************");   
  89.                         System.out.println("用户请求的资源是:" + resource);   
  90.                         System.out.println("请求的类型是: " + method);   
  91.   
  92.                         String params = null;   
  93.   
  94.                         if (resource.indexOf("?") > -1) {   
  95.                             params = resource   
  96.                                     .substring(resource.indexOf("?") + 1);   
  97.                             resource = resource.substring(0, resource   
  98.                                     .indexOf("?"));   
  99.                         }   
  100.   
  101.                         // 显示 POST 表单提交的内容, 这个内容位于请求的主体部分   
  102.                         if ("POST".equalsIgnoreCase(method)) {   
  103.                             if (params != null) {   
  104.                                 params += in.readLine();   
  105.                             }   
  106.                         }   
  107.   
  108.                         System.out.println("打印提交的数据:");   
  109.                         printParams(params);   
  110.   
  111.                         // 读取资源并返回给客户端   
  112.                         fileReaderAndReturn(resource, client);   
  113.                         // 关闭客户端链接   
  114.                         client.close();   
  115.                         System.out.println("客户端返回完成!");   
  116.                     } catch (Exception e) {   
  117.                         System.out.println("HTTP服务器错误:" + e.getMessage());   
  118.                     }   
  119.                 }   
  120.   
  121.             } catch (Exception e) {   
  122.                 System.out.println("HTTP服务器错误:" + e.getMessage());   
  123.             }   
  124.         }   
  125.     }   
  126.   
  127.     /**  
  128.      * 读取一个文件的内容并返回给浏览器端.  
  129.      *   
  130.      * @param fileName  
  131.      *            文件名  
  132.      * @param socket  
  133.      *            客户端 socket.  
  134.      * @throws IOException  
  135.      */  
  136.     void fileReaderAndReturn(String fileName, Socket socket) throws IOException {   
  137.         if ("/".equals(fileName)) {// 设置欢迎页面,呵呵!   
  138.             fileName = "/index.html";   
  139.         }   
  140.         fileName = fileName.substring(1);   
  141.   
  142.         PrintStream out = new PrintStream(socket.getOutputStream(), true);   
  143.         File fileToSend = new File(fileName);   
  144.   
  145.         String fileEx = fileName.substring(fileName.indexOf(".") + 1);   
  146.         String contentType = null;   
  147.         // 设置返回的内容类型   
  148.         // 此处的类型与tomcat/conf/web.xml中配置的mime-mapping类型是一致的。测试之用,就写这么几个。   
  149.         if ("htmlhtmxml".indexOf(fileEx) > -1) {   
  150.             contentType = "text/html;charset=GBK";   
  151.         } else if ("jpegjpggifbpmpng".indexOf(fileEx) > -1) {   
  152.             contentType = "application/binary";   
  153.         }   
  154.   
  155.         if (fileToSend.exists() && !fileToSend.isDirectory()) {   
  156.             // http 协议返回头   
  157.             out.println("HTTP/1.0 200 OK");// 返回应答消息,并结束应答   
  158.             out.println("Content-Type:" + contentType);   
  159.             out.println("Content-Length:" + fileToSend.length());// 返回内容字节数   
  160.             out.println();// 根据 HTTP 协议, 空行将结束头信息   
  161.   
  162.             FileInputStream fis = null;   
  163.             try {   
  164.                 fis = new FileInputStream(fileToSend);   
  165.             } catch (FileNotFoundException e) {   
  166.                 out.println("<h1>404错误!</h1>" + e.getMessage());   
  167.             }   
  168.             byte data[];   
  169.             try {   
  170.                 data = new byte[fis.available()];   
  171.   
  172.                 fis.read(data);   
  173.                 out.write(data);   
  174.             } catch (IOException e) {   
  175.                 out.println("<h1>500错误!</h1>" + e.getMessage());   
  176.                 e.printStackTrace();   
  177.             } finally {   
  178.                 out.close();   
  179.                 try {   
  180.                     fis.close();   
  181.                 } catch (IOException e) {   
  182.   
  183.                     e.printStackTrace();   
  184.                 }   
  185.             }   
  186.         } else {   
  187.             out.println("<h1>404错误!</h1>" + "文件没有找到");   
  188.             out.close();   
  189.   
  190.         }   
  191.   
  192.     }   
  193.   
  194.     void printParams(String params) throws IOException {   
  195.         if (params == null) {   
  196.             return;   
  197.         }   
  198.         String[] maps = params.split("&");   
  199.         for (String temp : maps) {   
  200.             String[] map = temp.split("=");   
  201.             System.out.println(map[0] + "==" + map[1]);   
  202.         }   
  203.     }   
  204.   
  205.     /** */  
  206.     /**  
  207.      * 启动 HTTP 服务器  
  208.      *   
  209.      * @param args  
  210.      */  
  211.     public static void main(String[] args) {   
  212.         try {   
  213.             if (args.length != 1) {   
  214.                 System.out.println("这是一个简单的web服务器 ,端口是: 80.");   
  215.             } else if (args.length == 1) {   
  216.                 PORT = Integer.parseInt(args[0]);   
  217.             }   
  218.         } catch (Exception ex) {   
  219.             System.err.println("服务器初始化错误" + ex.getMessage());   
  220.         }   
  221.   
  222.         new SimpleHttpServer();   
  223.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值