异构系统之间的HTTP通信

文章描述了一个简单的HTTPClient程序和HTTPServer程序的交互过程,客户端通过GET请求访问服务器,服务器解析请求并返回响应。此外,还提到了浏览器如何访问HTTPServer以及TOMCAT服务器的启动和访问。整个通信基于HTTP协议进行。
摘要由CSDN通过智能技术生成

   HTTPClient程序(HTTPClient.java):

package client;
import java.net.*;
import java.io.*;
import java.util.*;

public class HTTPClient {
  public static void main(String args[]){
    //确定HTTP请求的uri
    String uri="index.htm";
    if(args.length !=0)uri=args[0]; 
    
    doGet("localhost",8080,uri); //按照GET请求方式访问HTTPServer 
  }
  
  /** 按照GET请求方式访问HTTPServer */
  public static void doGet(String host,int port,String uri){
    Socket socket=null;
    
    try{
      socket=new Socket(host,port); //与HTTPServer建立FTP连接
    }catch(Exception e){e.printStackTrace();}
  
    try{
      /*创建HTTP请求 */
      StringBuffer sb=new StringBuffer("GET "+uri+" HTTP/1.1\r\n");
      sb.append("Accept: */*\r\n");
      sb.append("Accept-Language: zh-cn\r\n");
      sb.append("Accept-Encoding: gzip, deflate\r\n");
      sb.append("User-Agent: HTTPClient\r\n");
      sb.append("Host: localhost:8080\r\n");
      sb.append("Connection: Keep-Alive\r\n\r\n");
    
      /*发送HTTP请求*/
      OutputStream socketOut=socket.getOutputStream(); //获得输出流  
      socketOut.write(sb.toString().getBytes());
    
      Thread.sleep(2000); //睡眠2秒,等待响应结果
    
      /*接收响应结果*/
      InputStream socketIn=socket.getInputStream(); //获得输入流
      int size=socketIn.available();
      byte[] buffer=new byte[size];
      socketIn.read(buffer);
      System.out.println(new String(buffer)); //打印响应结果
      
    }catch(Exception e){ 
      e.printStackTrace();
    }finally{
      try{
        socket.close();  
      }catch(Exception e){e.printStackTrace();}
    }
  } //#doGet()
}


HTTPServer程序(HTTPServer.java)

package server;
import java.io.*;
import java.net.*;

public class HTTPServer{
  public static void main(String args[]) {
    int port;
    ServerSocket serverSocket;
      
    try { 
       port = Integer.parseInt(args[0]);
     }catch (Exception e) {
       System.out.println("port = 8080 (默认)");
       port = 8080; //默认端口为8080
     }

     try{
       serverSocket = new ServerSocket(port); 
       System.out.println("服务器正在监听端口:" 
                     + serverSocket.getLocalPort());
        
       while(true) { //服务器在一个无限循环中不断接收来自客户的TCP连接请求
         try{
           //等待客户的TCP连接请求
           final Socket socket = serverSocket.accept(); 
           System.out.println("建立了与客户的一个新的TCP连接,"
                +"该客户的地址为:"
                +socket.getInetAddress()+":" + socket.getPort());
          
           service(socket);  //响应客户请求
        }catch(Exception e){
          System.out.println("客户端请求的资源不存在");} 
      } //#while
    }catch (Exception e) {e.printStackTrace();}
  }

  /** 响应客户的HTTP请求 */
  public static void service(Socket socket)throws Exception{
    
    /*读取HTTP请求信息*/
    InputStream socketIn=socket.getInputStream(); //获得输入流
    Thread.sleep(500);  //睡眠500毫秒,等待HTTP请求  
    int size=socketIn.available();
    byte[] buffer=new byte[size];
    socketIn.read(buffer);
    String request=new String(buffer);
    System.out.println(request); //打印HTTP请求数据
    
    /*解析HTTP请求*/
    //获得HTTP请求的第一行
    int endIndex=request.indexOf("\r\n");
    if(endIndex==-1)
      endIndex=request.length();
    String firstLineOfRequest=
               request.substring(0,endIndex);

    //解析HTTP请求的第一行 
    String[] parts=firstLineOfRequest.split(" "); 
    String uri="";
    if(parts.length>=2)
      uri=parts[1]; //获得HTTP请求中的uri    

    /*决定HTTP响应正文的类型,此处作了简化处理*/
    String contentType;
    if(uri.indexOf("html")!=-1 || uri.indexOf("htm")!=-1)
      contentType="text/html";
    else if(uri.indexOf("jpg")!=-1 || uri.indexOf("jpeg")!=-1)
      contentType="image/jpeg";
    else if(uri.indexOf("gif")!=-1) 
      contentType="image/gif";
    else
      contentType="application/octet-stream";  //字节流类型
    
    
    /*创建HTTP响应结果 */
    //HTTP响应的第一行
    String responseFirstLine="HTTP/1.1 200 OK\r\n";
    //HTTP响应头
    String responseHeader="Content-Type:"+contentType+"\r\n\r\n";
    //获得读取响应正文数据的输入流
    InputStream in=HTTPServer
                     .class
                     .getResourceAsStream("root/"+uri);
    
    /*发送HTTP响应结果 */
    OutputStream socketOut=socket.getOutputStream(); //获得输出流
    //发送HTTP响应的第一行
    socketOut.write(responseFirstLine.getBytes());
    //发送HTTP响应的头
    socketOut.write(responseHeader.getBytes());
    //发送HTTP响应的正文
    int len=0;
    buffer=new byte[128];
    while((len=in.read(buffer))!=-1)
    socketOut.write(buffer,0,len);  
    
    Thread.sleep(1000);  //睡眠1秒,等待客户接收HTTP响应结果        
    socket.close(); //关闭TCP连接  
   }
}


1. HTTPClient程序与HTTPServer程序通信:
   将源程序编译成.class文件后,分别在HTTPClient.class与HTTPServer.class根目录(由于源代码有package声明,所以其根目录为client或server目录的上一级,同理执行java 命令时class文件也应该带包前缀,如java server.HTTPServer)下进入DOS(disk operate system)窗口,分别执行命令 java server.HTTPServer java client.HTTPClient 'root目录下文件名', 以运行HTTP服务端程序与HTTP客户端程序。客户端的请求文件如果默认的话为请求/root/index.htm文件(请求文件需要放在server包下的root目录中,即server/root/请求文件。启动后界面如下:

服务端程序启动:

客户端程序启动并请求(默认/root/index.htm):

服务端程序响应客户端请求:

注意:直接通过源程序重新编译生成的.class文件运行一般不会有问题。如果不是直接在本地编译生成的class文件,而是从其他地方直接获取到的,在DOS窗口直接运行时可能会报以下错误:Error: A JNI error has occurred, please check your installation and try again:原因是由于电脑上可能有多个版本的JDK,通过卸载旧版本的JDK,使java -version与 javac -version一致即可。当然,这种情况是你在通过本地直接编译生成class文件仍报错的情况。如果你本地本来编译与运行版本本来就一致的话,也就无需要进行卸载了,只需要重新使用javac命令编译源文件,再重新运行即可。

2. 浏览器访问HTTPServer程序:

   保持DOS窗口HTTPServer程序运行,在浏览器输入http://localhost:8080/hello6.htm即可。此时服务端窗口响应如下:


   有些浏览器可能会发出多个请求,不仅包含目标文件,也可能发出一些与服务器内部通信的请求,如果这些资源不存在,服务端程序会返回"客户端请求的资源不存在"提示.

3. HTTPClient程序访问TOMCAT服务器:

   关闭HTTPServer程序。在tomcat安装目录的bin目录下,通过startup.bat或者catalina run命令启动TOMCAT.(没安装得先安装下):

   未关闭HTTPServer程序启动TOMCAT时会报以下错误:

   这是由于同一台主机中不允许多个服务器进程监听同一个端口,而在HTTPServer程序及TOMCAT中都监听了8080端口,因此不能在同一台主机中同时启动它们。

4. 浏览器访问TOMCAT服务器:

   TOMCAT服务器启动后,浏览器输入http://localhost:8080/index.jsp,即可展示TOMCAT 索引页。

  综上,这些所有异构系统之前请求与响应的通信,都是基于遵守共同的HTTP协议实现的。

参考文档:Tomcat与Java Web开发技术详解
                  www.javathinker.net     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值