<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    夢想飛翔

    自強不息
    posts - 111, comments - 30, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
    /**
     * SimpleHttpServer.java
     
    */

    import java.io.*;
    import java.net.*;
    import java.util.StringTokenizer;

    /**
     * 一個簡單的用 Java Socket 編寫的 HTTP 服務器應用, 演示了請求和應答的協議通信內容以及
     * 給客戶端返回 HTML 文本和二進制數據文件(一個圖片), 同時展示了 404, 200 等狀態碼.
     * 首先運行這個程序,然后打開Web瀏覽器,鍵入http://localhost,則這個程序能夠顯示出瀏覽器發送了那些信息
     * 并且向瀏覽器返回一個網頁和一副圖片, 并測試同瀏覽器對話.
     * 當瀏覽器看到 HTML 中帶有圖片地址時, 則會發出第二次連接來請求圖片等資源.
     * 這個例子可以幫您理解 Java 的 HTTP 服務器軟件是基于 J2SE 的 Socket 等軟件編寫的概念, 并熟悉
     * HTTP 協議.
     * 相反的用 Telnet 連接到已有的服務器則可以幫忙理解瀏覽器的運行過程和服務器端的返回內容.
     *
     * <pre>
     *       當用戶在Web瀏覽器地址欄中輸入一個帶有http://前綴的URL并按下Enter后,或者在Web頁面中某個以http://開頭的超鏈接上單擊鼠標,HTTP事務處理的第一個階段--建立連接階段就開始了.HTTP的默認端口是80.
     *    隨著連接的建立,HTTP就進入了客戶向服務器發送請求的階段.客戶向服務器發送的請求是一個有特定格式的ASCII消息,其語法規則為:
     * < Method > < URL > < HTTP Version > <\n>
     * { <Header>:<Value> <\n>}*
     * <\n>
     * { Entity Body }
     *    請求消息的頂端是請求行,用于指定方法,URL和HTTP協議的版本,請求行的最后是回車換行.方法有GET,POST,HEAD,PUT,DELETE等.
     * 在請求行之后是若干個報頭(Header)行.每個報頭行都是由一個報頭和一個取值構成的二元對,報頭和取值之間以":"分隔;報頭行的最后是回車換行.常見的報頭有Accept(指定MIME媒體類型),Accept_Charset(響應消息的編碼方式),Accept_Encoding(響應消息的字符集),User_Agent(用戶的瀏覽器信息)等.
     *    在請求消息的報頭行之后是一個回車換行,表明請求消息的報頭部分結束.在這個\n之后是請求消息的消息實體(Entity Body).具體的例子參看httpRequest.txt.
     *     Web服務器在收到客戶請求并作出處理之后,要向客戶發送應答消息.與請求消息一樣,應答消息的語法規則為:
     * < HTTP Version> <Status Code> [<Message>]<\n>
     * { <Header>:<Value> <\n> } *
     * <\n>
     * { Entity Body }
     *    應答消息的第一行為狀態行,其中包括了HTTP版本號,狀態碼和對狀態碼進行簡短解釋的消息;狀態行的最后是回車換行.狀態碼由3位數字組成,有5類:
     * 參看:HTTP應答碼及其意義
     *
     * 1XX 保留
     * 2XX 表示成功
     * 3XX 表示URL已經被移走
     * 4XX 表示客戶錯誤
     * 5XX 表示服務器錯誤
     * 例如:415,表示不支持改媒體類型;503,表示服務器不能訪問.最常見的是200,表示成功.常見的報頭有:Last_Modified(最后修改時間),Content_Type(消息內容的MIME類型),Content_Length(內容長度)等.
     *    在報頭行之后也是一個回車換行,用以表示應答消息的報頭部分的結束,以及應答消息實體的開始.
     *    下面是一個應答消息的例子:
     * HTTP/1.0 200 OK
     * Date: Moday,07-Apr-97 21:13:02 GMT
     * Server:NCSA/1.1
     * MIME_Version:1.0
     * Content_Type:text/html
     * Last_Modified:Thu Dec 5 09:28:01 1996
     * Coentent_Length:3107
     *
     * <HTML><HEAD><TITLE></HTML>
     *
     * 在用Java語言實現HTTP服務器時,首先啟動一個java.net.ServerSocket在提?服務的端?上監聽連接.向客戶返回文本時,可以用PrintWriter,但是如果返回二進制數據,則必須使用OutputStream.write(byte[])方法,返回的應答消息字符串可以使用String.getBytes()方法轉換為字節數組返回,或者使用PrintStream的print()方法寫入文本,用write(byte[])方法寫入二進制數據.
     *
     * </pre>
     * 
    @author 劉長炯
     * 
    @version 1.0 2007-07-24 Sunday
     * 
    @version 1.1 2008-05-18 Sunday
     * 支持瀏覽器發出的POST信息打印,修正POST方式無法完成響應造成阻賽的BUG
     
    */
    public class SimpleHttpServer implements Runnable {
        
    /**
         *
         
    */
        ServerSocket serverSocket;
    //服務器Socket

        
    /**
         * 服務器監聽端口, 默認為 80.
         
    */
        
    public static int PORT=80;//標準HTTP端口

        
    /**
         * 開始服務器 Socket 線程.
         
    */
        
    public SimpleHttpServer() {
            
    try {
                serverSocket
    =new ServerSocket(PORT);
            } 
    catch(Exception e) {
                System.out.println(
    "無法啟動HTTP服務器:"+e.getLocalizedMessage());
            }
            
    if(serverSocket==null)  System.exit(1);//無法開始服務器
            new Thread(this).start();
            System.out.println(
    "HTTP服務器正在運行,端口:"+PORT);
        }

        
    /**
         * 運行服務器主線程, 監聽客戶端請求并返回響應.
         
    */
        
    public void run() {
            
    while(true) {
                
    try {
                    Socket client
    =null;//客戶Socket
                    int contentLength = 0;// 客戶端發送的 HTTP 請求的主體的長度
                    client=serverSocket.accept();//客戶機(這里是 IE 等瀏覽器)已經連接到當前服務器
                    if(client!=null) {
                        System.out.println(
    "連接到服務器的用戶:"+client);
                        
    try {
                            
    // 第一階段: 打開輸入流
                            BufferedReader in=new BufferedReader(new InputStreamReader(
                                    client.getInputStream()));

                            System.out.println(
    "客戶端發送的請求信息:\n===================");
                            
    // 讀取第一行, 請求地址
                            String line=in.readLine();
                            System.out.println(line);
                            String resource
    =line.substring(line.indexOf('/'),line.lastIndexOf('/')-5);
                            
    //獲得請求的資源的地址
                            resource=URLDecoder.decode(resource, "UTF-8");//反編碼 URL 地址
                            String method = new StringTokenizer(line).nextElement().toString();// 獲取請求方法, GET 或者 POST

                            
    // 讀取所有瀏覽器發送過來的請求參數頭部信息
                            while( (line = in.readLine()) != null) {
                                System.out.println(line);

                                
    // 讀取 POST 等數據的內容長度
                                if(line.startsWith("Content-Length")) {
                                    
    try {
                                        contentLength 
    = Integer.parseInt(line.substring(line.indexOf(':'+ 1).trim());
                                    } 
    catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }

                                
    if(line.equals("")) break;
                            }

                            
    // 顯示 POST 表單提交的內容, 這個內容位于請求的主體部分
                            if("POST".equalsIgnoreCase(method) && contentLength > 0) {
                                System.out.println(
    "以下內容為 POST 方式提交的表單數據");
                                
    for(int i = 0; i < contentLength; i++) {
                                    System.out.print((
    char)in.read());
                                }

                                System.out.println();
                            }

                            System.out.println(
    "請求信息結束\n===================");
                            System.out.println(
    "用戶請求的資源是:"+resource);
                            System.out.println(
    "請求的類型是: " + method);

                            
    // GIF 圖片就讀取一個真實的圖片數據并返回給客戶端
                            if(resource.endsWith(".gif")) {
                                fileService(
    "images/test.gif", client);
                                closeSocket(client);
                                
    continue;
                            }

                            
    // 請求 JPG 格式就報錯 404
                            if(resource.endsWith(".jpg")) {
                                                        PrintWriter out
    =new PrintWriter(client.getOutputStream(),true);
                            out.println(
    "HTTP/1.0 404 Not found");//返回應答消息,并結束應答
                            out.println();// 根據 HTTP 協議, 空行將結束頭信息
                            out.close();
                            closeSocket(client);
                            
    continue;
                            } 
    else {
                                
    // 用 writer 對客戶端 socket 輸出一段 HTML 代碼
                                PrintWriter out=new PrintWriter(client.getOutputStream(),true);
                                out.println(
    "HTTP/1.0 200 OK");//返回應答消息,并結束應答
                                out.println("Content-Type:text/html;charset=GBK");
                                out.println();
    // 根據 HTTP 協議, 空行將結束頭信息

                                out.println(
    "<h1> Hello Http Server</h1>");
                                out.println(
    "你好, 這是一個 Java HTTP 服務器 demo 應用.<br>");
                                out.println(
    "您請求的路徑是: " + resource + "<br>");
                                out.println(
    "這是一個支持虛擬路徑的圖片:<img src='abc.gif'><br>" +
                                        
    "<a href='abc.gif'>點擊打開abc.gif, 是個服務器虛擬路徑的圖片文件.</a>");
                                out.println(
    "<br>這是個會反饋 404 錯誤的的圖片:<img src='test.jpg'><br><a href='test.jpg'>點擊打開test.jpg</a><br>");
                                out.println(
    "<form method=post action='/'>POST 表單 <input name=username value='用戶'> <input name=submit type=submit value=submit></form>");
                                out.close();

                                closeSocket(client);
                            }
                        } 
    catch(Exception e) {
                            System.out.println(
    "HTTP服務器錯誤:"+e.getLocalizedMessage());
                        }
                    }
                    
    //System.out.println(client+"連接到HTTP服務器");//如果加入這一句,服務器響應速度會很慢
                } catch(Exception e) {
                    System.out.println(
    "HTTP服務器錯誤:"+e.getLocalizedMessage());
                }
            }
        }

        
    /**
         * 關閉客戶端 socket 并打印一條調試信息.
         * 
    @param socket 客戶端 socket.
         
    */
        
    void closeSocket(Socket socket) {
            
    try {
                socket.close();
            } 
    catch (IOException ex) {
                ex.printStackTrace();
            }
                                System.out.println(socket 
    + "離開了HTTP服務器");
        }

        
    /**
         * 讀取一個文件的內容并返回給瀏覽器端.
         * 
    @param fileName 文件名
         * 
    @param socket 客戶端 socket.
         
    */
            
    void fileService(String fileName, Socket socket)
        {

            
    try
            {
                PrintStream out 
    = new PrintStream(socket.getOutputStream(), true);
                File fileToSend 
    = new File(fileName);
                
    if(fileToSend.exists() && !fileToSend.isDirectory())
                {
                    out.println(
    "HTTP/1.0 200 OK");//返回應答消息,并結束應答
                    out.println("Content-Type:application/binary");
                    out.println(
    "Content-Length:" + fileToSend.length());// 返回內容字節數
                    out.println();// 根據 HTTP 協議, 空行將結束頭信息

                    FileInputStream fis 
    = new FileInputStream(fileToSend);
                    
    byte data[] = new byte[fis.available()];
                    fis.read(data);
                    out.write(data);
                    out.close();
                    fis.close();
                }
            }
            
    catch(Exception e)
            {
                System.out.println(
    "傳送文件時出錯:" + e.getLocalizedMessage());
            }
        }

        
    /**
         * 打印用途說明.
         
    */
        
    private static void usage() {
            System.out.println(
    "Usage: java SimpleHttpServer <port>\nDefault port is 80.");
        }


        
    /**
         * 啟動簡易 HTTP 服務器
         * 
    @param args
         
    */
        
    public static void main(String[] args) {
            
    try {
                
    if(args.length != 1) {
                    usage();
                } 
    else if(args.length == 1) {
                    PORT 
    = Integer.parseInt(args[0]);
                }
            } 
    catch (Exception ex) {
                System.err.println(
    "Invalid port arguments. It must be a integer that greater than 0");
            }

            
    new SimpleHttpServer();
        }

    }

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 美女视频黄频a免费| 91av视频免费在线观看| 亚洲第一精品在线视频| 毛片在线免费视频| 一级毛片大全免费播放下载| 亚洲天堂中文资源| 国产精品无码素人福利免费| 免费福利在线视频| 亚洲gay片在线gv网站| 国产成人高清亚洲| 999国内精品永久免费视频| 免费看内射乌克兰女| 亚洲视频在线观看免费| 国产无遮挡裸体免费视频 | 牛牛在线精品免费视频观看| 亚洲av无码不卡一区二区三区| 成年18网站免费视频网站| 中国一级特黄的片子免费 | 亚洲色大成网站www永久| 亚洲A丁香五香天堂网 | 亚洲va中文字幕无码久久| 成人毛片免费观看视频在线| a级午夜毛片免费一区二区| 亚洲欧美自偷自拍另类视| 亚洲av中文无码乱人伦在线咪咕| 国产一区二区三区免费在线观看| 国产精品爱啪在线线免费观看| 国产精品美女免费视频观看| 亚洲国产精品日韩av不卡在线| 亚洲AV电影院在线观看| 亚洲伦乱亚洲h视频| 少妇高潮太爽了在线观看免费| 午夜免费啪视频在线观看| xvideos永久免费入口| 亚洲AV日韩综合一区尤物| 亚洲精品在线观看视频| 亚洲色成人网站WWW永久| 免费一级肉体全黄毛片| 日韩视频在线免费观看| 又粗又大又黑又长的免费视频| 免费h视频在线观看|