通過前面相關的學習已經具備編寫自己HTTP服務器的能力,不管是通過阻塞還是非阻塞的方式都可以實現。但是這里需要對HTTP協議進行一個了解。
當用戶打開瀏覽器,輸入一個URL地址,就能收到遠程HTTP服務器發送過來的網頁。瀏覽器就是最常見的HTTP客戶程序。
HTTP協議規定,HTTP請求由3部分構成,分別是:
請求方式、URI、HTTP協議的版本請求頭請求正文下面是一個HTTP請求的例子:
GET / HTTP/1.1Host: www.google.com.hkConnection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36X-Chrome-UMA-Enabled: 1X-Client-Data: CJS2yQEipbbJAQjEtskBCOKYygEI+5zKAQipncoBAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdch, brAccept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4Cookie: NID=98=EmnQgFsnopWExg1XEQNjPR1FKwTo1T7Qk5fH94bdjmUqIdJ6L9C_LLziCX8_UcDv_iyo84kOgKMPTnP0pbfuJqigpoxfDWouhyKX58J_gn2HU1abg7UJFik2bhwSHIU9kpJIEvQ6rtigHffscUqanx5_Tb-F1yq_4WiaBGjINA_A9siROY-WPTka8eRvElgyXk7koHQKGET / HTTP/1.1
分別表示 請求方式(GET) URI(/) 協議版本(HTTP/1.1) 根據HTTP協議,HTTP請求可以使用多種方式:
請求頭: 請求頭包含許多有關客戶端環境和請求正文的有用信息。例如,請求頭可以申明瀏覽器類型,所用的語言,請求正文的類型,已經請求正文的長度。
Host: www.google.com.hkConnection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36X-Chrome-UMA-Enabled: 1X-Client-Data: CJS2yQEIpbbJAQjEtskBCOKYygEI+5zKAQipncoBAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdch, brAccept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4Cookie: NID=98=EmnQgFsnopWExg1XEQNjPR1FKwTo1T7Qk5fH94bdjmUqIdJ6L9C_LLziCX8_UcDv_iyo84kOgKMPTnP0pbfuJqigpoxfDWouhyKX58J_gn2HU1abg7UJFik2bhwSHIU9kpJIEvQ6rtigHffscUqanx5_Tb-F1yq_4WiaBGjINA_A9siROY-WPTka8eRvElgyXk7koHQK請求正文:
HTTP協議規定,請求頭和請求正文之間必須以空行分給(只有CRLF[就是回車(CR, ASCII 13, /r) 換行(LF, ASCII 10, /n)。]符號的行),這個空行表示請求頭已經結束,接下來是請求正文。下面是POST請求方式提交的表單數據
username=weixin&passWord=1234與HTTP請求相比,HTTP響應格式也由3部分構成:
HTTP協議版本、狀態碼、描述響應頭(Response Header)響應正文(Response Content)下面是一個HTTP響應的例子:
HTTP/1.1 200 OKDate: Sun, 05 Mar 2017 04:31:31 GMTExpires: -1Cache-Control: private, max-age=0Content-Type: text/html; charset=UTF-8Server: gwsX-XSS-Protection: 1; mode=blockX-Frame-Options: SAMEORIGINAlt-Svc: quic=":443"; ma=2592000; v="36,35,34"Transfer-Encoding: chunkedHTTP協議的版本、狀態碼、描述
HTTP響應的第一行包括服務器使用的HTTP協議的版本,狀態碼、以及對狀態的代碼的描述。這三項以空格分開。HTTP/1.1 200 OK
狀態碼:
狀態碼是一個3位整數,以1、2、3、4或5開頭。
1XX :信息提示,表示臨時的響應。2XX:響應成功,表示服務器成功接收了客戶端的請求。3XX:重定向。4XX:客戶端錯誤,表明客戶端請求了不正確的資源或請求格式錯誤。5XX:服務器錯誤,表明服務器由于遇到某種錯誤而不能響應客戶請求。以下是一些常見的狀態碼:
200:響應成功。400:錯誤的請求??蛻舭l送的HTTP請求不正確。404:文件不存在。在服務端沒有客戶端請求的文檔。405:服務器不支持客戶端的請求方式。500:服務器內部錯誤。響應頭: 響應頭也和請求頭一樣包含許多有用的信息。例如,服務器類型,正文類型。
Content-Type: text/html; charset=UTF-8Server: gws請求正文 在上面的響應格式中沒有列出響應正文,因為是通過chrome查看的。chrome將響應正文放到另外的地方,因為響應正文一般都比較大。如下圖 通過HTTP響應頭與響應正文之間必須用空行分隔。
通過ServerSocketChannel
、SocketChannel
、Buffer
以及線程池實現:
訪問方式 在瀏覽器輸入 http://localhost/login.html 出現login頁面,輸入username和password。
在服務端控制臺輸出如下:
這個圖的請求數據就是完整的包含:請求方式,URI、協議版本、請求頭、請求正文。
歡迎關注微信公眾號 在路上的coder
每天分享優秀的java技術文章,還有學習視頻分享! 掃描二維碼關注:
新聞熱點
疑難解答