国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

用java實現的一個簡單web服務器程序

2019-11-17 04:00:26
字體:
來源:轉載
供稿:網友
一、首先來看一下http的報文結構

1、請求報文

一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組成,下圖給出了請求報文的一般格式。



(1)請求行

請求行由請求方法字段、URL字段和HTTP協議版本字段3個字段組成,它們用空格分隔。例如,GET /index.html HTTP/1.1。

HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。這里介紹最常用的GET方法和POST方法。

GET:當客戶端要從服務器中讀取文檔時,使用GET方法。GET方法要求服務器將URL定位的資源放在響應報文的數據部分,回送給客戶端。使用GET方法時,請求參數和對應的值附加在URL后面,利用一個問號(“?”)代表URL的結尾與請求參數的開始,傳遞參數長度受限制。例如,/index.jsp?id=100&op=bind。

POST:當客戶端給服務器提供信息較多時可以使用POST方法。POST方法將請求參數封裝在HTTP請求數據中,以名稱/值的形式出現,可以傳輸大量數據。

(2)請求頭部

請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知服務器有關于客戶端請求的信息,典型的請求頭有:

User-Agent:產生請求的瀏覽器類型。

Accept:客戶端可識別的內容類型列表。

Host:請求的主機名,允許多個域名同處一個ip地址,即虛擬主機。

(3)空行

最后一個請求頭之后是一個空行,發送回車符和換行符,通知服務器以下不再有請求頭。

(4)請求數據

請求數據不在GET方法中使用,而是在POST方法中使用。POST方法適用于需要客戶填寫表單的場合。與請求數據相關的最常使用的請求頭是Content-Type和Content-Length。

2、響應報文

響應報文的格式大體上和請求報文類似,只是第一行有所不同,讀者可以自己在網上查找這方面的介紹,這里不再贅述。

二、程序的實現

程序的實現步驟如下:

1、接收客戶端瀏覽器的請求;

2、創建一個新的線程,用于處理該次請求;

3、讀取報文數據,判斷報文正確與否,分析報文內容;

4、創建響應報文,發送到客戶端;

5、結束該處理線程,處理其他客戶請求;

程序代碼如下:

view plaincopy to clipboardPRint?
import java.net.*;   
import java.io.*;   
import java.util.*;   
import java.lang.*;   
public class WebServer {   
    public static void main(String [] args){   
        int port;   
        ServerSocket server_socket;   
        try{   
            port=Integer.parseInt(args[0]);   
        }   
        catch (Exception e){   
            port=8080;   
        }   
        try{   
            server_socket=new ServerSocket(port);   
            System.out.println("WebServer running on port"+server_socket.getLocalPort());   
            while(true){   
                Socket socket=server_socket.accept();   
                System.out.println("New connection accepted"+socket.getInetAddress()+":"+socket.getPort());   
                //針對特定的請求創建處理該請求的線程   
                try{   
                    httpRequestHandler request=new httpRequestHandler(socket);   
                    Thread thread=new Thread(request);   
                    thread.start();   
                }   
                catch(Exception e){   
                    System.out.println(e);   
                }   
            }   
        }   
        catch(IOException e){   
            System.out.println(e);   
        }   
    }   
}   
  
//處理請求的線程類   
class httpRequestHandler implements Runnable{   
       
    final static String CRLF="/r/n";   
    Socket socket;   
    InputStream input;   
    OutputStream output;   
    BufferedReader br;   
    //判斷請求的文件類型是否正確   
    boolean fileType=true;   
       
    //初始化參數   
    public httpRequestHandler(Socket socket) throws Exception{   
        this.socket=socket;   
        this.input=socket.getInputStream();   
        this.output=socket.getOutputStream();   
        this.br=new BufferedReader(new InputStreamReader(socket.getInputStream()));   
    }   
    //啟動該線程   
    public void run(){   
        try{   
            processRequest();   
        }   
        catch(Exception e){   
            System.out.println(e);   
        }   
    }   
    //處理請求的核心函數   
    private void processRequest() throws Exception{   
        while(true){   
            String headerLine=br.readLine();   
            System.out.println("the client request is"+headerLine);   
            if(headerLine.equals(CRLF)||headerLine.equals(""))   
                break;   
            StringTokenizer s=new StringTokenizer(headerLine);   
            String temp=s.nextToken();   
            if(temp.equals("GET")){   
                   
                String fileName=s.nextToken();   
                fileName="."+fileName;   
                FileInputStream fis=null;   
                boolean fileExists=true;   
                   
                if(!(fileName.endsWith(".htm")||fileName.endsWith(".html")))   
                {   
                    this.fileType=false;   
                    try{   
                        fis=new FileInputStream("error.html");   
                    }   
                    catch(FileNotFoundException e){   
                        fileExists=false;   
                    }      
                }   
                else{   
                    try{   
                        fis=new FileInputStream(fileName);   
                    }   
                    catch(FileNotFoundException e){   
                        fileExists=false;   
                    }   
                }   
                   
                String serverLine="Server:a simple java WebServer";   
                String statusLine=null;   
                String contentTypeLine=null;   
                String entityBody=null;   
                String contentLengthLine="error";   
               
                if(fileExists&&this.fileType){   
                    statusLine="HTTP/1.0 200 OK"+CRLF;   
                    contentTypeLine="Content-type:"+this.contentType(fileName)+CRLF;   
                    contentLengthLine="Content-Length:"+(new Integer(fis.available())).toString()+CRLF;   
                }   
                else{   
                    if(fileExists&&this.fileType==false){   
                        statusLine="HTTP/1.0 400 BadRequest"+CRLF;   
                        contentTypeLine="text/html";   
                        entityBody="<HTML>400 Not BadRequest</TITLE></HEAD>"+   
                        "<BODY>400 BadRequest"+   
                        "<br>usage:http://yourHostName:port/"+   
                        "fileName.html</BODY></HTML>";     
                    }   
                    else if(fileExists==false){   
                        statusLine="HTTP/1.0 404 Not Found"+CRLF;   
                        contentTypeLine="text/html";   
                        entityBody="<HTML>404 Not Found</TITLE></HEAD>"+   
                        "<BODY>404 Not Found"+   
                        "<br>usage:http://yourHostName:port/"+   
                        "fileName.html</BODY></HTML>";   
                    }   
                }   
                output.write(statusLine.getBytes());   
                output.write(serverLine.getBytes());   
                output.write(contentTypeLine.getBytes());   
                output.write(contentLengthLine.getBytes());   
                output.write(CRLF.getBytes());   
                   
                if(fileExists&&this.fileType){   
                    sendBytes(fis,output);   
                    fis.close();   
                }   
                else{   
                    output.write(entityBody.getBytes());   
                }   
            }   
        }   
        try{   
            output.close();   
            br.close();   
            socket.close();   
        }   
        catch(Exception e){}   
    }   
       
    //將客戶端請求的頁面發送出去   
    private static void sendBytes(FileInputStream fis,OutputStream os) throws Exception{   
        byte[] buffer=new byte[1024];   
        int bytes=0;   
        while((bytes=fis.read(buffer))!=-1){   
            os.write(buffer,0,bytes);   
        }      
    }   
    //設置contentType的內容     
    private static String contentType(String fileName){   
        if(fileName.endsWith(".htm")||fileName.endsWith(".html")){   
            return "text/html";   
        }   
        return "fileName";   
    }   
           
}  
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兰考县| 许昌市| 桃园县| 鄂尔多斯市| 耒阳市| 永城市| 青铜峡市| 临汾市| 肃南| 柞水县| 高州市| 巨野县| 沛县| 特克斯县| 美姑县| 建湖县| 寿阳县| 山阳县| 顺昌县| 延长县| 灵璧县| 宁蒗| 遂川县| 安康市| 尚义县| 长垣县| 交口县| 沾化县| 江门市| 韶山市| 拉萨市| 崇文区| 台东市| 隆化县| 家居| 桓仁| 治县。| 象山县| 洱源县| 宿州市| 赤水市|