由於作者我遇到了一些疑難問題,原本上週應該到來的更新,被我拖稿了。。。
接下來進入我們今天的主題,Linux的網絡編程。其實我只是根據socket編程通過簡 單一個TCP 和HTTP程序來幫助大家瞭解一下Linux的網絡編程,真正的網絡編程還 需要諸位自行挖掘,在真諦中體會強大。
所謂的TCP是一種傳輸協議,TCP/IP則是數據傳輸的協議簇,TCP是一種面向連接 的、可靠的、基於字節流的通信協議,TCP工作在傳輸層,UDP也是傳輸層協議,但 比較TCP相對簡單,這裏就不做具體介紹。
TCP的連接有三次握手,斷開連接有四次握手
客戶端發送SYN報文給服務器端
服務器端收到SYN報文,迴應一個SYN和ACK報文
客戶端收到服務器端的SYN報文,迴應一個ACK報文
三次握手完成,TCP客戶端和服務器端成功地建立連接,可以開始傳輸數據了。
由於TCP的半關閉機制導致斷開連接需要四次握手
某一斷使用close,並且發送FIN信號,表示數據發送完畢
接受FIN的對方,發送確認
過一段響應時間,接受FIN一方未收到對方數據傳輸,調用close,發送FIN斷開連接
經過四次握手雙方都斷開了連接
Linux下的SOCKET編程比較Windows有許多方便之處,尤其是SOCK_RAW
下面來介紹程序的流程和實現方式,我儘可能不用實現代碼,使用僞代碼更好的幫助 大家理解
客戶端:
首先是封裝struct sockaddr_in 用於存儲服務端和本端的ip、端口等信息結構體
填充sockaddr_in定義的一個結構體,注意字節順序的轉換
客戶端使用connect對服務器端進行連接,之後使用內核函數read來接收數據即可
如果使用多線程編程,數據傳輸更加有調理,也不會出現死鎖的狀況。
將接收函數或者發送函數放到一個新開的線程中即可,無需兩者都放入線程中
在接收函數中注意清空緩衝區,不然會出現字符串亂碼。
服務器端:
相對於客戶端,服務器端就比較麻煩,需要綁定端口和IP信息,需要循環接收客戶端 連接請求,同時還要發送和接收數據。
首先封裝struct sockaddr_in,這裏要使用兩個,一個用於存儲服務器本身,一個存 儲客戶端,一個存儲客戶端。
bind綁定本地信息,listen監聽訪問本地端口的客戶端,accept接收訪問服務器的用 戶信息。
Linux下不需要輸出話WSA(Windows Sockets Asynchronous的簡稱)。可以直接 使用相關處理函數。
接下來,介紹HTTP的GET方法實現
HTTP是應用層協議,其訪問方式和SOCKET編程中一樣,對IP:端口進行訪問。
只是建立連接之後,發送的數據有所區別,這個就需要對HTTP響應頭、請求頭進 行分析。
通過抓包可以看出請求頭、響應頭。
Telnet www.baidu.com 80
HEAD /index.html HTTP/1.1
(空兩行)
可以使用telnet對報文進行查看
編寫發送的數據包以上述格式封裝。
獲得的響應包數據是對應網站的HTML佈局文件。