本篇文章主要介紹go語言基于tcp協議實現簡單的http服務器,大家可以學習到:
1.怎樣實現一個簡單的http服務器
2.通過錯誤的http協議格式加深對http協議的理解
平時我們使用的http服務器,如:apache、nginx都是一個完整而且功能強大的服務器,如果我們不去看源碼無法很好地理解http服務器的內部實現。如果我們不去自己實現一個簡單的http服務器,可能就無法很好地理解http協議,我們學習應該不僅要知其然還要知其所以然。
本篇文章從tcp協議開始介紹,之后使用tcp socket按照http協議格式發送數據到客戶端,這里的客戶端指的就是瀏覽器。
傳輸控制協議(TCP,Transmission Control Protocol)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。
tcp協議屬于傳輸層協議,http協議屬于應用層協議,http協議位于tcp協議之上,也是http協議是基于tcp協議實現的。很多應用層協議都是基于tcp協議實現的,如:文件傳輸協議ftp、ssh協議、telenet協議等。
下面開始我們的編程之旅!
首先監聽本地tcp 8888端口
listen, err := net.Listen("tcp", "127.0.0.1:8888")
之后打印監聽信息
fmt.Println("server start listening on port 8888")
接著延時關閉tcp流
defer listen.Close()
之后for循環進入監聽,如果有連接進來啟動goroutine進行處理
go
接著我們來看下handleClient函數的實現
go
handleClient函數里面首先定義了響應體,打印響應體的長度。之后定義響應頭,響應頭以“HTTP/1.1 200 OK\n”開始,這是http協議的標準響應頭,之后定義響應類型和響應體的長度。響應頭和響應體之間以“\n\r\n”分割。
最后以字節格式發送給瀏覽器。
下面我們來看下執行效果吧!在瀏覽器中輸入
http://127.0.0.1:8888/
瀏覽器
可以看到瀏覽器中顯示出我們啟動的服務器返回的數據。Response Headers中的響應頭正是我們設置的。
恭喜你,完成了自己的http服務器!
但是凡事我們要舉一反三,我們再來試一下如果http狀態是500時,返回的結果是什么?
http
瀏覽器
這個http 500就是我們在開發中經常遇到的,現在我們自己模擬實現了。
我們可以嘗試去掉響應頭和響應體之間的分隔符
http
我們看下結果
瀏覽器
結果是瀏覽器無法識別,這就是為什么會有http協議,先規定協議各家瀏覽器按照協議實現,這樣就不會出現問題。