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

首頁 > 編程 > Java > 正文

Java實現簡易Web服務器

2019-11-26 14:33:09
字體:
來源:轉載
供稿:網友

眾所周知Web服務器與客戶端之間的通信是使用HTTP協議的。HTTP是一個客戶端和服務器端請求和應答的標準(TCP)。因為HTTP協議是基于TCP協議的,所以我將使用JAVA中的Socket完成這個簡易的Web服務器。關于HTTP更詳細的資料,各位可以查閱相關資料進行了解。
在服務器編寫之前,我們還是先來看一下瀏覽器與服務器之間通信的規則到底如何。
首先,我們是用ServerSocket來模擬一個服務端,通過瀏覽器訪問,查看瀏覽器請求的內容:

import java.io.BufferedWriter;import java.io.InputStream;import java.io.OutputStreamWriter;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.net.Socket;import org.junit.Test;/** * HTTP協議測試 *  * @author jianggujin *  */public class HQHttpProtocolTest{ @Test public void server() throws Exception {  ServerSocket serverSocket = new ServerSocket(80);  Socket socket = serverSocket.accept();  InputStream stream = socket.getInputStream();  int r = -1;  while ((r = stream.read()) != -1)  {   System.out.print((char) r);  } }}

使用junit運行,并通過瀏覽器訪問:http://127.0.0.1,我們可以看到控制臺上輸出瀏覽器的請求內容如下:

GET / HTTP/1.1Host: 127.0.0.1Connection: keep-aliveAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36Accept-Encoding: gzip,deflate,sdchAccept-Language: zh-CN,zh;q=0.8

為了更好的分析請求內容,我們編寫一個HTML頁面提交一些數據,再次查看請求內容:

<!DOCTYPE html><html><head><meta charset="utf-8"><title>test</title></head><body><form method="post" action="http://127.0.0.1?test=123"><input type="text" name="name"/><input type="submit"/></form></body></html>

在輸入框中輸入bob,點擊按鈕提交,觀察控制臺輸出:

POST /?test=123 HTTP/1.1Host: 127.0.0.1Connection: keep-aliveContent-Length: 8Cache-Control: max-age=0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Origin: nullUser-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36Content-Type: application/x-www-form-urlencodedAccept-Encoding: gzip,deflate,sdchAccept-Language: zh-CN,zh;q=0.8name=bob

我們來分析一下這段請求內容:
第一行:由三部分組成,中間以空格分開,第一部分為請求方法(GET、POST),第二部分為請求路徑以及查詢參數,第三部分為HTTP協議版本(HTTP/1.1)
第二行到第十行:請求的頭信息,請求頭名稱與值之間通過:分隔
第十一行:空行
第十二行:提交的表單內容
綜上,我們可以得到如下結論:請求信息第一行為請求方法、請求路徑以及查詢參數、HTTP協議版本,通過/r/n換行后緊跟著請求頭信息,各頭信息之間通過/r/n換行,請求頭信息結束后跟著一個空行,空行之后緊跟著一行為請求數據,需要注意的是,這里面只模擬了最簡單的表單提交,至于復雜的文件提交等,這里面不討論,請求內容格式略有不同。
至此,客戶端請求的內容我們已經知道了,下面我們再來看看服務端在接收到請求后響應數據的格式,我們新建一個Web項目用于測試,編輯Html頁面內容如下:

<!DOCTYPE html><html><head><meta charset="utf-8"><title>test</title></head><body>this is test page.</body></html>

啟動服務器,然后編寫客戶端測試代碼,獲得服務端返回數據:

import java.io.BufferedWriter;import java.io.InputStream;import java.io.OutputStreamWriter;import java.net.ServerSocket;import java.net.Socket;import org.junit.Test;/** * HTTP協議測試 *  * @author jianggujin *  */public class HQHttpProtocolTest{ public void server() throws Exception {  ServerSocket serverSocket = new ServerSocket(80);  Socket socket = serverSocket.accept();  InputStream stream = socket.getInputStream();  // BufferedInputStream inputStream = new BufferedInputStream(stream);  int r = -1;  while ((r = stream.read()) != -1)  {   System.out.print((char) r);  } } @Test public void client() throws Exception {  Socket socket = new Socket("127.0.0.1", 80);  BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(   socket.getOutputStream()));  writer.write("GET /Servlet/test.html HTTP/1.1/r/n");  writer.write("Host: 127.0.0.1/r/n");  writer.write("Connection: keep-alive/r/n");  writer.write("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8/r/n");  writer.write("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36/r/n");  writer.write("Accept-Encoding: gzip,deflate,sdch/r/n");  writer.write("Accept-Language: zh-CN,zh;q=0.8/r/n");  writer.write("/r/n");  writer.flush();  InputStream stream = socket.getInputStream();  int r = -1;  while ((r = stream.read()) != -1)  {   System.out.print((char) r);  } }}

運行程序獲得服務器返回內容如下:

HTTP/1.1 200 OKServer: Apache-Coyote/1.1Accept-Ranges: bytesETag: W/"129-1456125361109"Last-Modified: Mon, 22 Feb 2016 07:16:01 GMTContent-Type: text/htmlContent-Length: 129Date: Mon, 22 Feb 2016 08:08:32 GMT<!DOCTYPE html><html><head><meta charset="utf-8"><title>test</title></head><body>this is test page.</body></html>

同樣的,我們來分析一下這段返回消息:
第一行由三部分組成,中間以空格分開,第一部分為HTTP協議版本(HTTP/1.1),第二部分為響應狀態碼,第三部分為響應狀態描述
第二行到第七行為響應頭信息,響應頭名稱與值之間通過:分隔
第八行:空行
第九行到結束:響應內容
綜上,我們可以得到如下結論:請求信息第一行為HTTP協議版本、響應狀態碼、響應狀態描述,通過/r/n換行后緊跟著響應頭信息,各頭信息之間通過/r/n換行,響應頭信息結束后跟著一個空行,空行之后緊跟著響應數據,需要注意的是,除這種響應外,其實還有其他的相應方式,比如chunk,此處不討論,可查閱相關資料。

到現在為止,我們已經分析完了客戶端的請求內容格式以及服務端相應內容的格式,這一篇就到此為止了,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 凤山县| 山东省| 银川市| 潍坊市| 长岭县| 中卫市| 建宁县| 新河县| 通江县| 安新县| 林甸县| 怀柔区| 黄山市| 黑龙江省| 霸州市| 富阳市| 吴忠市| 盐边县| 阳东县| 武义县| 旅游| 黄浦区| 浏阳市| 通道| 缙云县| 汝阳县| 堆龙德庆县| 潍坊市| 确山县| 太湖县| 台江县| 冷水江市| 马鞍山市| 诸城市| 屏东市| 马尔康县| 钟山县| 昌黎县| 招远市| 丰城市| 平舆县|