一、基本思路:
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,但是,这里判断不严格,只是捕获出来了,但是不影响程序继续运行。