深入理解HTTP的最好方式就是自己造一個輪子(1)
本文所有程式碼均託管在Esimorp/SimpleHttpServer
我想大多數的開發者應該都知道HTTP協議是基於TCP/IP協議的,那麼在網路傳輸的過程中,
請求資料
和響應資料究竟是如何傳輸的呢?今天就讓我們來一探究竟。
public
class
HttpServer
{
public
HttpServer
(
int
port
)
throws
IOException
{
ServerSocket
serverSocket
=
new
ServerSocket
(
port
);
Socket
socket
=
serverSocket
。
accept
();
BufferedReader
input
=
new
BufferedReader
(
new
InputStreamReader
(
socket
。
getInputStream
()));
BufferedWriter
output
=
new
BufferedWriter
(
new
OutputStreamWriter
(
socket
。
getOutputStream
()));
String
line
=
null
;
int
index
=
0
;
while
((
line
=
input
。
readLine
())
!=
null
)
{
System
。
out
。
(
index
);
System
。
out
。
println
(
line
);
if
(
line
。
length
()
==
0
)
break
;
index
++;
}
output
。
write
(
“Hello World”
);
output
。
flush
();
input
。
close
();
output
。
close
();
}
}
這是一個簡單的Java的TCP Server程式,我們建立了一個HttpServer類,在
建構函式
中接受了一個int型的引數,用作這個HttpServer的監聽埠。然後我們建立了一個SocketServer繫結在傳進來的port上,然後取得SocketServer的Socket,獲取這個socket的輸入流和輸出流,因為在Http協議中大部分內容都是String型別的並且以行來分割資料,所以這裡我們用BufferedReader和BufferedWriter來操作輸入和輸出。
InputStream的read方法是阻塞的,所以當沒有資料寫入的時候程式會在while迴圈處阻塞,當有資料流入的時候才會執行while迴圈的迴圈體部分。在迴圈體中,我們將收到輸入資料中的每一行,我們用index作為行號,將每一行的內容打印出來。由於當HTTP的報文的Header塊結束的時候會有一個CRLF作為Header塊的結束標記,這裡我們先簡寫成判斷length。
當所有資料接收完畢的時候,我們將會在輸出中輸出一個
字串
“Hello World”最為一個好開頭。然後將輸入和輸出流關閉。
public
class
Main
{
public
static
void
main
(
String
args
[])
{
try
{
new
HttpServer
(
8081
);
}
catch
(
IOException
e
)
{
e
。
printStackTrace
();
}
}
}
在程式入口處我們建立這個HttpServer類,然後將埠繫結到8081,然後使用瀏覽器訪問我們建立的HttpServer,到底會發生什麼呢?
哈哈,久違的Hello World出現了,瀏覽器把我們輸出的字串正確的渲染出來了。大家可能會發現有一條請求沒有正確相應,可是我們明明只有一串字元,並沒有其它的任何內容,為什麼會又有一條請求呢?
這個
favicon。ico
檔案做建站的開發者可能會熟悉,但是做API的開發者可能不會太清楚。
這個檔案就是網站的圖示,如圖紅框處就是知乎的圖示。
這個圖示在html中沒有任何設定的情況下,瀏覽器預設favicon。ico在網站的根目錄,在載入完document後會再次發起請求,訪問這個檔案,而我們的伺服器只相應第一次請求,所以這次請求就會出現ERR_CONNECTION_REFUSED異常。
好了現在讓我們看看我們的伺服器輸出了什麼呢?
第0行:Http請求的起始行,包含了 請求方法,請求路徑,和HTTP
協議版本
,這三個內容用空格進行分割,這次請求的方法是GET 路徑是 / 也就是根目錄,HTTP協議版本是1。1
第1-9行: Http請求的首部,也就是常說的Header,這裡面放置的是該Http請求的附加資訊,每條資訊的名字和內容用冒號分割,結尾處用CRLF表示結束。
第10行: 表示Http請求的首部的
終止符
,也就是說首部到此結束。
有關於Http的首部我們以後會更詳細的說明,《
HTTP權威指南
》是一本很棒的書,有興趣的朋友可以透過讀這本書來了解更多關於Http首部的知識。
由於瀏覽器訪問URL所使用的方法是GET,所以這裡面我們沒有看到請求體,這個在以後的內容中也會出現的。
好了,到這裡我們已經學會了做了一個非常非常簡單的HTTP伺服器,當有請求的時候,這個伺服器會響應一個內容為“Hello World”的字串,然後將這個HTTP伺服器關閉。要想想,當人類文明毀滅的時候,你就變成了重建網際網路的中堅力量,想一想是不是還有一些激動呢?
下一篇文章中,我們將會了解到更多的關於HTTP報文的知識
未完待續。。。