這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近買了本書《HTTP權威指南》,看了第一章,看到書上說通過telnet類比HTTP請求,我這個學渣就發現自己沒學過電腦網路。
今天翻了一下考研指定教材《電腦網路》,裡面也以訪問清華大學首頁為例詳細講了通訊過程:
- 瀏覽器分析連結指向頁面的URL。
- 瀏覽器向DNS請求解析www.tsinghua.edu.cn的IP地址。
- 網域名稱系統DNS解析出清華大學伺服器的IP地址為166.111.4.100。
- 瀏覽器與伺服器建立TCP串連(在伺服器端IP地址是166.111.4.100,連接埠是80)。
- 瀏覽器發出取檔案命令:GET /chn/yxsz/index.htma
- 伺服器www.tsinghua.edu.cn給出響應,把檔案index.htm發送給瀏覽器。
- 釋放TCP串連。
- 瀏覽器顯示“清華大學院系設定”檔案index.htm中的所有文本。
HTTP協議就是:與指定IP和連接埠建立TCP串連,然後通過串連發送請求命令、頭和資料。伺服器響應的資料也會通過這個請求得到。
考過研的連這個都不懂的傷不起啊。
在這裡我主要想自己基於TCP串連來類比一次HTTP請求。測試是否能發送HTTP的頭資訊,通過User-Agent欄位來類比。還要發送Body資訊測試Body的發送。
1. telnet類比請求
$ telnet blog.cyeam.com 80GET / HTTP/1.0
此命令可以建立串連,建立之後,輸入請求命令,方法為GET,路徑是根路徑\
,連接埠是80。然後再輸入兩個斷行符號,就可以發送請求了。這裡會返迴響應狀態代碼、回應標頭和Body。響應返回後,這次的telnet請求也會隨之關閉。POST的發送可以參考HTTP POST via telnet - Burak’s logs
2. POSTMAN類比請求
POSTMAN是一個Chrome外掛程式,很強大,能夠類比HTTP請求,查看請求和響應的全部內容。我一般還會用它的Preview功能,這樣能看到所有的請求資料。
3. beego類比伺服器
也可以用公網上的伺服器進行測試,但是沒有辦法查看伺服器端收到的請求詳細內容,用beego搭了伺服器來測試(伺服器還是beego最熟。。。)。
beego當中擷取User-Agent通過this.Ctx.Request.UserAgent()
實現。擷取Body內容通過string(this.Ctx.Input.RequestBody)
實現,還需要在設定檔加入copyrequestbody = true
,預設取到的Body是空的。beego伺服器功能的驗證可以通過POSTMAN類比。
4. 基於TCP通訊端實現HTTP的POST請求
通過POSTMAN的Preview查看完整請求和telnet使用,發現HTTP請求的命令、頭和Body是通過分行符號\n
來區分的。POSTMAN抓到的如下:
POST HTTP/1.1Host: localhost:8080Cache-Control: no-cachePostman-Token: 649dbec6-4f13-7064-67f0-11461281ceb2This is body
可以得到結論:HTTP命令、頭和Body通過分行符號來區分。第一行是請求命令,跟著是HTTP頭,他們之間通過一個分行符號區分,頭直接也是通過一個分行符號區分。兩個分行符號之後,是Body資訊。
通過大Golang發送請求:
conn.Write([]byte("POST / HTTP/1.0\nUser-Agent: Cyeam\nContent-Length: 4\n\nBody\r\n\r\n"))
需要注意一點,如果要傳入Body內容,必須在頭當中加入長度資訊Content-Length: 4
,否則伺服器依然無法擷取,反正beego是這樣,可能是擷取Body前會先判斷一下長度,如果是0就不讀取Body資訊了。完整代碼借鑒了《Go 語言編程》第五章的內容。
本文所涉及到的完整源碼請測試用戶端和測試伺服器。
參考文獻
- 【1】《HTTP權威指南》
- 【2】《電腦網路 - 謝希仁》
- 【3】HTTP POST via telnet - Burak’s logs
原文連結:基於TCP通訊端,通過Golang類比HTTP請求,轉載請註明來源!