研究了一天這個玩意感覺挺有意思的。
剛開始是什麼都不懂,現在寫出來一段代碼感覺略微有點意思了。
下面我分享一下學習過程和自己的理解。
整體過程大概就是如下情況:
先搜了一下別人的寫這個東西的代碼。
研究了一下代碼中一些難理解的東西。慢慢就寫出來了。
簡單分析:
創建一個socket套接字連接主機
發送GET報文頭字符串
接收
存放
准備工作:
connect()和服務器建立連接
send() recv() 都是在利用套接字
用戶提供一個網址,我們分析網址。
網址中包含的信息 有些是要填入sockaddr地址信息中 ,有些是要填入GET報頭文
我們能得知信息有 主機名 資源路徑 端口
例如一個 www.baidu.com/1.html 主機名www.baidu.com 資源路徑 /1.html 端口沒有 就 默認 80
建立連接 connect()函數搞定
參數中需要socket 和 sockaddr 前者就是套接字,後者是一個套接字地址結構
可以從sockaddr_in 強制轉化過來 這個是另一種套接字地址結構體
需要提供 端口和 ip地址
端口 我們分析網址就能得到
ip地址 是用gethostbyname()這個函數搞定
函數名就挺形象的 通過主機名字獲得host信息
意思就是 從 www.baidu.com 主機名 獲得host信息
然後我們從信息裡面把ip地址提取出來
GET報文頭 需要主機名 資源路徑 這兩樣網址中都提供了
發送 send()這個函數搞定
接收 recv()這個函數搞定
細分邏輯:
主要是學習這些函數以及結構的過程,和一些簡單的邏輯組織。
分析網址 這個都在string.h
從host結構中獲得ip地址填入套接字地址結構 這個查閱一下gethostbyname()和sockaddr以及sockaddr_in
連接connect()
存放GET報文頭,把報文頭用字符串函數組建起來,放在數組或者其他。。
發送send()
如果你發送的GET報文頭得到了回應,目標就會傳送你要的信息回來
接收recv()
信息可能很多,可能不能一次性接收完,分多次。用memcpy()和malloc()以及realloc()
memcpy() copy字節數到目標 malloc()聲明一定大小的內存區域 realloc()改變內存區域大小
什麼時候接收完 如果套接字中有接收的內容就一直接收。沒有就等待,直到超時,然後返回0.
這個超時時間限定是可以設置的。setsockopt()這個函數。可以設置接收和發送
int nNetTimeout = 5000;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, sizeof(int));
遺留問題的思考:對於接收到數據處理。編碼問題。我覺得套接字中傳輸的是數據,不是字符串。
正文這個我覺得倒是好理解,有人用utf8寫了一個html網頁文件保存在服務器,我們所獲取的正文應該是這個用utf8編碼寫的數據 (我猜的)
但是接收到的報文頭是什麼編碼呢,我們用什麼簡單的方法把它們分離,沒有去研究。。有機會再看看