zoukankan      html  css  js  c++  java
  • Java实践:一个简易的http server和client的java源码学习和总结。

    一、基本思路:

    1、服务器端通过socket(), 监听在TCP 8080端口,等待客户端来连接。

    2、服务器端解析客户端的HTTP请求中的URI值,把本地的目录下指定文件通过java的读取文件的方式getResourceAsStream()发送给客户端。

    3、客户端把应用程序的第一个参数作为目标文件,传到HTTP请求中。

    二、总结:

    1、服务器端终究是通过解析HTTP请求中的内容,取到目标文件,并且服务器端的字节码文件,必须和root目录放一起。

    2、java有现成的类的方法,获得socket中的内容,服务器端的成功返回,也是服务器自行构造的。

    三、源码

    1、服务器端代码:

      1 package server;
      2 import java.io.*;
      3 import java.net.*;
      4 
      5 public class HTTPServer{
      6   public static void main(String args[]) {
      7     int port;
      8     ServerSocket serverSocket;
      9       
     10     try { 
     11        port = Integer.parseInt(args[0]);
     12      }catch (Exception e) {
     13        System.out.println("port = 8080 (默认)");
     14        port = 8080; //默认端口为8080
     15      }
     16 
     17      try{
     18        serverSocket = new ServerSocket(port); 
     19        System.out.println("服务器正在监听端口:" + serverSocket.getLocalPort());
     20         
     21        while(true) { //服务器在一个无限循环中不断接收来自客户的TCP连接请求
     22          try{
     23            //等待客户的TCP连接请求
     24            final Socket socket = serverSocket.accept(); 
     25            System.out.println("建立了与客户的一个新的TCP连接,该客户的地址为:"+
     26                 socket.getInetAddress()+":" + socket.getPort());
     27           
     28            service(socket);  //响应客户请求
     29         }catch(Exception e){e.printStackTrace();} 
     30       } //#while
     31     }catch (Exception e) {e.printStackTrace();}
     32   }
     33 
     34   /** 响应客户的HTTP请求 */
     35   public static void service(Socket socket)throws Exception{
     36     
     37     /*读取HTTP请求信息*/
     38     InputStream socketIn=socket.getInputStream(); //获得输入流
     39     Thread.sleep(500);  //睡眠500毫秒,等待HTTP请求  
     40     int size=socketIn.available();
     41     byte[] requestBuffer=new byte[size];
     42     socketIn.read(requestBuffer);
     43     String request=new String(requestBuffer);
     44     System.out.println(request); //打印HTTP请求数据
     45      
     46     /*解析HTTP请求*/
     47     //获得HTTP请求的第一行
     48     String firstLineOfRequest=request.substring(0,request.indexOf("
    "));
     49     //解析HTTP请求的第一行 
     50     String[] parts=firstLineOfRequest.split(" ");
     51     String getMethod = "GET";
     52     if(true != parts[0].equals("GET"))
     53     {
     54         System.out.println("client Bad request:" + parts[0] + " method length=" + parts[0].length() ); //打印错误的请求
     55         System.out.println("correct request is:" + getMethod ); 
     56     }
     57     
     58     String uri=parts[1]; //获得HTTP请求中的uri
     59     
     60     /*决定HTTP响应正文的类型*/
     61     String contentType;
     62     if(uri.indexOf("html")!=-1 || uri.indexOf("htm")!=-1)
     63       contentType="text/html";
     64     else if(uri.indexOf("jpg")!=-1 || uri.indexOf("jpeg")!=-1)
     65       contentType="image/jpeg";
     66     else if(uri.indexOf("gif")!=-1) 
     67       contentType="image/gif";
     68     else
     69       contentType="application/octet-stream"; 
     70     
     71     
     72     /*创建HTTP响应结果 */
     73     //HTTP响应的第一行
     74     String responseFirstLine="HTTP/1.1 200 OK
    ";
     75     //HTTP响应头
     76     String responseHeader="Content-Type:"+contentType+"
    
    ";
     77     //获得读取响应正文数据的输入流
     78     InputStream in=HTTPServer.class.getResourceAsStream("root/"+uri);
     79     
     80     /*发送HTTP响应结果 */
     81     OutputStream socketOut=socket.getOutputStream(); //获得输出流
     82     //发送HTTP响应的第一行
     83     socketOut.write(responseFirstLine.getBytes());
     84     //发送HTTP响应的头
     85     socketOut.write(responseHeader.getBytes());
     86     //发送HTTP响应的正文
     87     int len=0;
     88     byte[] buffer=new byte[128];
     89     while((len=in.read(buffer))!=-1)
     90     socketOut.write(buffer,0,len);  
     91     
     92     Thread.sleep(1000);  //睡眠1秒,等待客户接收HTTP响应结果        
     93     socket.close(); //关闭TCP连接  
     94     
     95   }
     96 }
     97 
     98 
     99 
    100 
    101 /****************************************************
    102  * 作者:孙卫琴                                     *
    103  * 来源:<<Tomcat与Java Web开发技术详解>>           *
    104  * 技术支持网址:www.javathinker.org                *
    105  ***************************************************/

    客户端代码:

     1 package client;
     2 import java.net.*;
     3 import java.io.*;
     4 import java.util.*;
     5 
     6 public class HTTPClient {
     7   public static void main(String args[]){
     8     //确定HTTP请求的uri
     9     String uri="index.htm";
    10     if(args.length !=0)uri=args[0]; 
    11     
    12     doGet("localhost",8080,uri); //按照GET请求方式访问HTTPServer 
    13   }
    14   
    15   /** 按照GET请求方式访问HTTPServer */
    16   public static void doGet(String host,int port,String uri){
    17     Socket socket=null;
    18     
    19     try{
    20       socket=new Socket(host,port); //与HTTPServer建立FTP连接
    21     }catch(Exception e){e.printStackTrace();}
    22   
    23     try{
    24       /*创建HTTP请求 */
    25       StringBuffer sb=new StringBuffer("GET1 "+uri+" HTTP/1.1
    ");
    26       sb.append("Accept: */*
    ");
    27       sb.append("Accept-Language: zh-cn
    ");
    28       sb.append("Accept-Encoding: gzip, deflate
    ");
    29       sb.append("User-Agent: HTTPClient
    ");
    30       sb.append("Host: localhost:8080
    ");
    31       sb.append("Connection: Keep-Alive
    
    ");
    32     
    33       /*发送HTTP请求*/
    34       OutputStream socketOut=socket.getOutputStream(); //获得输出流  
    35       socketOut.write(sb.toString().getBytes());
    36     
    37       Thread.sleep(2000); //睡眠2秒,等待响应结果
    38     
    39       /*接收响应结果*/
    40       InputStream socketIn=socket.getInputStream(); //获得输入流
    41       int size=socketIn.available();
    42       byte[] buffer=new byte[size];
    43       socketIn.read(buffer);
    44       System.out.println(new String(buffer)); //打印响应结果
    45       
    46     }catch(Exception e){ 
    47       e.printStackTrace();
    48     }finally{
    49       try{
    50         socket.close();  
    51       }catch(Exception e){e.printStackTrace();}
    52     }
    53   } //#doGet()
    54 }
    55 
    56 
    57 
    58 
    59 /****************************************************
    60  * 作者:孙卫琴                                     *
    61  * 来源:<<Tomcat与Java Web开发技术详解>>           *
    62  * 技术支持网址:www.javathinker.org                *
    63  ***************************************************/

    四、运行方法:

    1、先运行服务器端,以便等待客户端的连接:

         

     2、再启动客户端,发送http 请求:

           

    3、观察服务器端的输出:

        

        特别说明,在本程序中,已经判断出客户端写错了GET请求,写成了GET1,但是,这里判断不严格,只是捕获出来了,但是不影响程序继续运行。

        

  • 相关阅读:
    程序员职业路线图
    程序员职业路线图
    高级程序员和低级程序员的区别
    高级程序员和低级程序员的区别
    高级程序员和低级程序员的区别
    使用fastai完成图像分类
    hibernate JPA
    mongodb增删改查
    【树莓派从入门到入土】1.什么是树莓派?
    输入一个url之后到底发生了什么
  • 原文地址:https://www.cnblogs.com/zhouhaibing/p/8597155.html
Copyright © 2011-2022 走看看