用java套接字建立HTTP客戶與服務器程序

最近再學習java的web編程,發現用java建立一個小的服務器和客戶端是如此的簡單,引用經典圖書《Tomcat與Java Web開發技術詳解(第二版)》(孫衛琴)html

根據書中案例敲代碼本身學習,放這裏記錄一下,以便複習:)java

服務器端程序,接收客戶端程序發出的HTTP請求,把它打印到控制檯,而後解析HTTP請求,並向客戶端發回相應的HTTP響應。web

HTTPServer類中service()方法中,先讀取HTTP請求數據,而後得到HTTP請求中的URL,隨後建立一個讀取本地文件的輸入流,該文件的路徑由URI決定編程

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;
        }
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("服務器正在監聽端口:"+serverSocket.getLocalPort());
            while(true) {
                try {
                //等待客戶端的TCP鏈接請求
                final Socket socket = serverSocket.accept();
                System.out.println("創建了與客戶的一個新的TCP鏈接,該客戶的地址爲:"
                +socket.getInetAddress()+":"+socket.getPort());
                service(socket);
                } catch(Exception e) {e.printStackTrace();}
            } //#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("http請求數據: \n"+request);    //打印HTTP請求數據
        
        /*解析HTTP請求*/
        //得到HTTP請求的第一行
        String firstLineOfRequest=request.substring(0,request.indexOf("\r\n"));
        //解析HTTP請求的第一行
        String[] parts = firstLineOfRequest.split(" ");
        String 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鏈接
    }
}

服務器

客戶端程序,以GET方式向HTTP服務器發送HTTP請求,而後把接收到的HTTP響應結果打印到控制檯,並無進行解析app

 

HTTPClient.javasocket

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

public class HTTPClient {
    public static void main(String args[]) {
        //肯定HTTP請求的uri
        String uri = "Welcome.html";
        if(args.length !=0)
            uri=args[0];
        
        doGet("localhost",8080,uri);    //按照GET請求方式訪問HTTPServer
    }
    
    /**按照GET請求方式訪問HTTPServer */
    private static void doGet(String host, int port, String uri) {
        // TODO Auto-generated method stub
        Socket socket = null;
        try{
            socket = new Socket(host,port);        //與HTTPServer創建TCP鏈接
        }catch (Exception e){e.printStackTrace();}
    
    try{
        /*建立HTTP請求*/
        StringBuffer sb = new StringBuffer("GET "+uri+" HTTP/1.1\r\n");        //HTTP請求的第一行
        //HTTP請求頭
        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();}
        }
    }
}學習

 

客戶端參數&服務端本地文件Hello1.html:.net

<html>
<head>
<title>
HelloWorld!
</title>
</head>
<body>
<h1>Hello</h1>    
<img src="xiongbenxiong.gif" align="middle"/>
</body>
</html>


運行結果:

瀏覽器顯示:

相關文章
相關標籤/搜索