陳碩《網路程式設計實戰》01 網路程式設計概要

2021-10-10 17:02:39 字數 3437 閱讀 5988

站在巨人的肩膀之上。

《unix網路程式設計》是理查德.斯蒂文斯的傳世之作,本課程認為你已經大致讀過本書,具備基本的tcp/ip知識,例如ip位址埠號等等,而且用sockets api 寫過echo sever 這樣簡單的網路程式,這是這門課程的前提條件。

本課程針對的是 linux 系統,使用 c++、python、go 幾門語言,其中 c++ 用的最多。

理查德.史蒂文斯在2023年出版了《unix網路程式設計》的第一版,之後他寫了《unix環境高階程式設計》和《tcp/ip詳解》 三卷本。

然後他開始寫《unix網路程式設計》第二版,原計畫分三卷出版:

第一卷講網路程式設計api,2023年出版,這本書主要講的是sockets apis,他也講了現在已經淘汰了的xti,這個不去談它;

第二卷其實和網路程式設計關係不大,主要講程序間通訊,2023年出版,你可以認為是講多程序和多執行緒的併發程式設計,這兩本書都是用 c 語言;

第三卷最令人期待的一本書,講網路程式設計的應用,可惜,理查德.斯蒂文斯2023年9月1號不幸去世,本書就沒有下文了。

當然了,我這門課程不是想續上《unix網路程式設計》第三卷,而是補充一些實際的程式設計例子,幫助讀者更好地掌握《unix網路程式設計》第一卷的內容。

我認為,《unix網路程式設計》第一卷有兩樣東西強調的不夠:

第乙個是訊息格式的處理,特別是在非阻塞io下如何正確的處理tcp分包這個沒有講到。

第二個呢,是這本書講授的併發模型稍顯陳舊,高併發服務往往採用事務驅動加非阻塞io的辦法,這是傳統的,在《unix網路程式設計》中,分量不足,只有一章,而有一本書專門講這方面內容,是叫《面向模式的軟體架構》第二卷,講各種併發模型,因此本門課程也會參考這本書,這本書是2023年出版的。

《unix網路程式設計》第三版是由另外乙個人續寫的,在2023年出版,如果你要去買書的話,可以考慮買他的第三版。

一說起網路程式設計,很多人就往高效能上想,而這門課程強調的是可以測量的效能,測不出來的效能指標是沒有意義的,還有呢,我想避免那種基於猜測、猜想的優化,因為我發現有些優化,除了讓**變得更複雜而難以維護之外,對效能沒有實質的提公升,網路程式設計有很多以訛傳訛的講究,在一些中文論壇上面看出來,比如民間傳說要儘量減少動態記憶體分配,使用stl更是罪大惡極,但是你知道linux核心,從網絡卡收到乙個資料報到經過協議棧把資料傳給應用程式,這個過程中一共會分配釋放多少次記憶體呢?

你知道網路是分層的,一般程式設計師關注四層:乙太網層,ip層、傳輸層和應用層。

我們在談幾層的時候,術語要準確,乙太網 frame 叫幀,ip packet 叫分組,tcp segment叫分節,應用層通常我們談訊息(message),注意「ip的分組」和「ip的分片」是兩個事情,一般我們不用管ip分片。

網路程式設計是乙個入門容易精通難的事情,初學者有一些常見的錯誤,這裡列了一些,在後面的課程中還會具體的結合例子來講,這裡先大致提一下:

乙個是《unix網路程式設計》的示例**,往往把網路io和業務邏輯穿插在一起,這固然比較容易寫出緊湊易讀的**,但是在大型專案中,這種做法的可維護性比較低,因為不是每個人都那麼精通網路程式設計的方方面面的細節,如果他熟悉業務邏輯,那他在寫業務邏輯的時候,可能一不小心就引入網路程式設計方面的bug,應該是盡量避免在網路程式設計中把和socket api 打交道**和業務邏輯穿插在一起。

第二個呢,也是中文論壇上,長期出現的專案,有人說tcp不可靠,收到的資料不完整,這個話題以後我還會專門講,主要是涉及tcp連線斷開的時機與條件,close太早的話,有可能導致協議棧傳送rst分節,將連線重置,資料自然就收不完了,在阻塞程式設計中可以使用so_linger這個選項,在非阻塞so_linger這個選項沒用,我們現在從應用層的協議上入手解決問題,你在設計應用層協議的時候,把tcp連線的斷開,要放到協議設計的考慮當中去。

第三個呢,tcp是乙個位元組流協議,他保證位元組按順序到達,但不保留訊息的邊界,因為對於tcp本身來說沒有訊息概念,就說你傳送一堆的資料過去。那麼,tcp我們檢測程式的乙個辦法,就是如果他乙個位元組乙個位元組收到的話,你程式應該也能正常工作。在應用程式中,我們要設計並實現tcp分包的邏輯,把tcp的位元組流切分成乙個乙個可以分開的訊息,這方面有一些小坑,初學者容易掉進去,課程以後會講到。

第四個呢,初學者常見的乙個設計失誤,直接傳送c語言的結構體,這個問題有兩個:

第乙個呢,他要考慮對齊,有的人會直接修改全域性的對齊的方式,他把pack設成1,直接導致第三方library擴大,因為破壞了api二進位制介面;

還有問題是在於,高度的不可擴充套件。因為你要增加乙個字段的話,就所有的客戶端服務端都要公升級,而且如果有一方不是用c語言寫的話,你就要手工實現 pack、unpack 的**,也是維護上有很大的代價,這麼做就一開始用傳送c strcut,可能是受了學tcp的教材的影響,因為tcp/ip的header,它就用的是定長的那種欄位的格式,而且它裡面用了bit field(位域),所以可能有的人照貓畫虎說,既然tcp/ip自己這麼用,那我自己寫應用的時候也是用struct來表示訊息,這個情況我認為通常應該避免的。

第五個是乙個具體的小坑,就是tcp的「自連線」。你發現tcp的客戶端往本機的服務端發起連線的時候,如果伺服器沒有起來,在一定條件下,客戶端會自己和自己建立乙個連線,比方說從localhost的埠54321,再連到了54321埠,你收發資料出現鬼打牆的現象,發個資料,自己收回來,就跟出現loop迴圈程式設計的時候一樣,你知道現象就很很好辦,你發現種情況就把連線斷開,重新試就行了。

最後呢,非阻塞網路程式設計中還有很多很多坑,乙個好的庫呢,應該把大多數坑都填上,同時程式設計師,你要明白非阻塞網路程式設計的特點,避免別人把坑填好了,你自己再把坑挖開掉進去。

現在千兆網早就普及了,在很多機房裡面,萬兆網,實際的乙太網也已經不堪使用,那麼你很自然的想法,千兆網到底有多快?如果我們用tcp來傳輸資料的話,這裡有簡單的計算,它把從乙太網的層面訊息的每部分的長度列出來,算出來乙個最大的頻寬是117兆位元組每秒,或者用二進位制的 mega,bit 計算的話是112,下面我們先來做個實驗,驗證一下計算是否正確。

陳碩《網路程式設計實戰》目錄

00.前言 01.網路程式設計概要.mkv 02.乙個tcp的簡單實驗.mkv 03.課程內容大綱.mkv 04.回顧基礎的sockets api.mkv 05.ttcp 概覽.mkv 06.使用ttcp進行網路傳輸效能測試.mkv 07.阻塞io下的ttcp實驗.mkv 8.tcp自連線.mkv ...

python3網路程式設計實戰

客戶端程式 usr bin env python3 coding utf 8 version python 3.6.3 tools pycharm 2017.3.3 date 2018 7 24 11 06 author cdl import socket import time class cha...

39 網路程式設計

http協議,hyper text transfer protocol 超文字傳輸協議 是用於從全球資訊網伺服器傳送超文字到本地瀏覽器的傳輸議,http是乙個應用層協議,由請求和響應構成,是乙個標準的客戶端伺服器模型。c s模式 client和server常常分別處在相距很遠的兩台計算機上,clie...