一、基本思路:
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("\r\n")); 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\r\n"; 75 //HTTP响应头 76 String responseHeader="Content-Type:"+contentType+"\r\n\r\n"; 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\r\n"); 26 sb.append("Accept: */*\r\n"); 27 sb.append("Accept-Language: zh-cn\r\n"); 28 sb.append("Accept-Encoding: gzip, deflate\r\n"); 29 sb.append("User-Agent: HTTPClient\r\n"); 30 sb.append("Host: localhost:8080\r\n"); 31 sb.append("Connection: Keep-Alive\r\n\r\n"); 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,但是,这里判断不严格,只是捕获出来了,但是不影响程序继续运行。