本周開始,開發(fā)一個(gè)簡(jiǎn)單的HttpServer,歡迎大家指正。
中間借鑒了一些網(wǎng)友的代碼,在此致謝,參見(jiàn)如下:
/**
* 一個(gè)簡(jiǎn)單的用 Java Socket 編寫的 HTTP 服務(wù)器應(yīng)用, 演示了請(qǐng)求和應(yīng)答的協(xié)議通信內(nèi)容以及 給客戶端返回 HTML 文本和二進(jìn)制數(shù)據(jù)文件(一個(gè)圖片), 同時(shí)展示了 404, 200 等狀態(tài)碼.
* 首先運(yùn)行這個(gè)程序,然后打開Web瀏覽器,鍵入
http://localhost,則這個(gè)程序能夠顯示出瀏覽器發(fā)送了那些信息 并且向?yàn)g覽器返回一個(gè)網(wǎng)頁(yè)和一副圖片, 并測(cè)試同瀏覽器對(duì)話. 當(dāng)瀏覽器看到 HTML 中帶有圖片地址時(shí),
* 則會(huì)發(fā)出第二次連接來(lái)請(qǐng)求圖片等資源. 這個(gè)例子可以幫您理解 Java 的 HTTP 服務(wù)器軟件是基于 J2SE 的 Socket 等軟件編寫的概念, 并熟悉 HTTP 協(xié)議. 相反的用 Telnet
* 連接到已有的服務(wù)器則可以幫忙理解瀏覽器的運(yùn)行過(guò)程和服務(wù)器端的返回內(nèi)容.
*
* <pre>
* 當(dāng)用戶在Web瀏覽器地址欄中輸入一個(gè)帶有http://前綴的URL并按下Enter后,或者在Web頁(yè)面中某個(gè)以http://開頭的超鏈接上單擊鼠標(biāo),HTTP事務(wù)處理的第一個(gè)階段--建立連接階段就開始了.HTTP的默認(rèn)端口是80.
* 隨著連接的建立,HTTP就進(jìn)入了客戶向服務(wù)器發(fā)送請(qǐng)求的階段.客戶向服務(wù)器發(fā)送的請(qǐng)求是一個(gè)有特定格式的ASCII消息,其語(yǔ)法規(guī)則為:
* < Method > < URL > < HTTP Version > <\n>
* { <Header>:<Value> <\n>}*
* <\n>
* { Entity Body }
* 請(qǐng)求消息的頂端是請(qǐng)求行,用于指定方法,URL和HTTP協(xié)議的版本,請(qǐng)求行的最后是回車換行.方法有GET,POST,HEAD,PUT,DELETE等.
* 在請(qǐng)求行之后是若干個(gè)報(bào)頭(Header)行.每個(gè)報(bào)頭行都是由一個(gè)報(bào)頭和一個(gè)取值構(gòu)成的二元對(duì),報(bào)頭和取值之間以":"分隔;報(bào)頭行的最后是回車換行.常見(jiàn)的報(bào)頭有Accept(指定MIME媒體類型),Accept_Charset(響應(yīng)消息的編碼方式),Accept_Encoding(響應(yīng)消息的字符集),User_Agent(用戶的瀏覽器信息)等.
* 在請(qǐng)求消息的報(bào)頭行之后是一個(gè)回車換行,表明請(qǐng)求消息的報(bào)頭部分結(jié)束.在這個(gè)\n之后是請(qǐng)求消息的消息實(shí)體(Entity Body).具體的例子參看httpRequest.txt.
* Web服務(wù)器在收到客戶請(qǐng)求并作出處理之后,要向客戶發(fā)送應(yīng)答消息.與請(qǐng)求消息一樣,應(yīng)答消息的語(yǔ)法規(guī)則為:
* < HTTP Version> <Status Code> [<Message>]<\n>
* { <Header>:<Value> <\n> } *
* <\n>
* { Entity Body }
* 應(yīng)答消息的第一行為狀態(tài)行,其中包括了HTTP版本號(hào),狀態(tài)碼和對(duì)狀態(tài)碼進(jìn)行簡(jiǎn)短解釋的消息;狀態(tài)行的最后是回車換行.狀態(tài)碼由3位數(shù)字組成,有5類:
* 參看:HTTP應(yīng)答碼及其意義
*
* 1XX 保留
* 2XX 表示成功
* 3XX 表示URL已經(jīng)被移走
* 4XX 表示客戶錯(cuò)誤
* 5XX 表示服務(wù)器錯(cuò)誤
* 例如:415,表示不支持改媒體類型;503,表示服務(wù)器不能訪問(wèn).最常見(jiàn)的是200,表示成功.常見(jiàn)的報(bào)頭有:Last_Modified(最后修改時(shí)間),Content_Type(消息內(nèi)容的MIME類型),Content_Length(內(nèi)容長(zhǎng)度)等.
* 在報(bào)頭行之后也是一個(gè)回車換行,用以表示應(yīng)答消息的報(bào)頭部分的結(jié)束,以及應(yīng)答消息實(shí)體的開始.
* 下面是一個(gè)應(yīng)答消息的例子:
* 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語(yǔ)言實(shí)現(xiàn)HTTP服務(wù)器時(shí),首先啟動(dòng)一個(gè)java.net.ServerSocket在提供服務(wù)的端口上監(jiān)聽連接.向客戶返回文本時(shí),可以用PrintWriter,但是如果返回二進(jìn)制數(shù)據(jù),則必須使用OutputStream.write(byte[])方法,返回的應(yīng)答消息字符串可以使用String.getBytes()方法轉(zhuǎn)換為字節(jié)數(shù)組返回,或者使用PrintStream的print()方法寫入文本,用write(byte[])方法寫入二進(jìn)制數(shù)據(jù).
*
* </pre>
*
* @author 劉長(zhǎng)炯
* @version 1.0 2007-07-24 Sunday
*/