前言
? ? ? ?
? ? ? ? 以<深入理解計算機系統>(以下稱“本書”)內容為基礎,對程序的整個過程進行梳理。本書內容對整個計算機系統做了系統性導引,每部分內容都是單獨的一門課.學習深度根據自己需要來定
引入
? ? ? ? 接續上一篇理解計算機系統_網絡編程(1)-CSDN博客
國際互聯網
? ? ? ? Internet的硬件與軟件組織
? ? ? ? 本書原話如下(黑體字):
? ? ? ? 全球IP因特網是最著名和最成功的互聯網絡實現.以下是一個客戶端--服務器應用程序的基本硬件和軟件組織
? ? ? ? ?每臺因特網主機都運行實現TCP/IP協議,幾乎每個現代計算機系統都支持這個協議?
? ? ? ? ----解讀:從圖中可以看出,TCP/IP協議由操作系統內核支持,并對外提供套接字接口.程序員是面向套接字接口編程的.用戶代碼將由系統調用轉化成機器代碼控制硬件(網絡適配器)完成數據傳送.
? ? ? ? 程序員怎樣看待網絡
? ? ? ? 從程序員的角度,我們可以把因特網看做一個世界范圍的主機集合,滿足以下特性:
? ? ? ? ? ? ? ? 1.主機集合被映射為一組32位的IP地址
? ? ? ? ? ? ? ? 2.這組IP地址被映射為一組稱為因特網域名的標識符
? ? ? ? ? ? ? ? 3.因特網主機上的進程能夠通過連接和任何其他因特網主機上的進程通信? ---黑體字是原話
????????----解讀:不管主機是客戶端還是服務器,都以IP地址在網絡上標識其身份.對于服務器而言,IP地址被映射成因特網域名.客戶端與服務器之間通過連接進行通信
====================內容分割線↓============================================
? ? ? ? IPv4和IPv6???????
? ? ? ? 理論上IPv4已經夠用了
????????問題:互聯網上主機擁有自己的IP地址,IP地址是32位,最大數是40多億,意味著超過這個數字的主機設備將不能聯網,但事實真的如此嗎?
????????答案是否定的.之前筆者提到過以多個數據來建立"層級"或者更大數據的例子.例如:8位機理論上可以尋址個數也可以是無限的,原理是通過"指針"來延展.單個8位能表達256個數,而當8位數據放的是指針,用2個8位數據就能表達65536個數,即達到16位數的效果.
? ? ? ? IP地址的延展基于相同的思想.一個IP地址本來用作映射一臺主機,當用一個IP地址映射一個網關的時候,這個IP地址可以表示一個子網絡里的n臺主機,如果n臺主機仍覺得不夠,那么在子網絡中的某個IP地址再次用作網關,這時最初的那個IP地址可以表示(n-1)*(n-1)臺主機,依此類推.當然這是一種簡化的表達,其中可能牽涉到帶寬分配,路由算法等細節,筆者不知道具體實現,但有這樣的技術.
? ? ? ? 這種思想也可以放入數據結構中,建立層級的數據類型,筆者以前帖子中有所提及,可翻看
====================內容分割線↑============================================
接下來部分內容逐一分析IP地址,域名映射,主機通信
IP地址
? ? ? ? 本書原話:一個IP地址就是一個32位無符號整數,網絡程序將IP地址存放在以下結構中
struct in_addr{uint32_t s_addr;
}
? ? ? ? ----解讀:一個標量地址被放入一個結構中,有些令人費解,用個全局變量就可以表達的.而本書對此表示承認,說"是套接字接口早期實現的不幸產物",目前體會不到,不作解讀.
大端法和小端法
? ? ? ? 本書原話:在IP地址結構中存放的地址總是以(大端法)網絡字節順序存放的,即使主機字節順序是小端法.
? ? ? ? ----解讀:大端法和小端法沒有多難,但可以加深對數據存儲和訪問的理解,所以值得一說.
????????假設有個32位地址0x12345678,里面的數字是0x11223344.用C語言表示如下:
int *p= 0x12345678; //指針指向該地址
*p=0x11223344; //賦值
p+=4; //往下偏移4,指向0x1234567c
????????有一個問題:每次指針偏移4,指向下一個地址,那中間地址數據在哪里?0x12345679,0x1234567a,0x1234567b?
????????實際上*p=0x11223344這個32位數包含了這三個字節的值.一個字節是8位,最大表示0xff(十進制255) .*p把這四個字節的值一起表達了,0x12345678這個地址里的數是0x44,地址79里的數是0x33,地址7a里的數是0x22,地址7b里的值是0x11.圖示如下:
????????大小端法在字節順序上有所不同,圖示如下:
? ? ? ? 注意:筆者查了某度,說法似乎不一致.細想是一樣的,把左邊定義成小端或者右邊定義成小端,不影響結果.
????????相比較,小端法適合思維習慣(當然也可能是先入為主,先學主機表示再學網絡).
????????對于程序員來說,大端法和小端法不會影響代碼,不必去糾結.那么為什么要作區別呢?筆者估計在機器層面,把數據從網絡上取下來的時候,位置不同數據不同.程序員只需要記住某種情況下需要調用這個api.
IP地址和點分十進制串之間的轉換
? ? ? ? 具體不知道在什么情況下能用得上,所以不做過多解讀.
? ? ? ? 記住一個例子:十進制串0xffffffff對應的IP地址是255.255.255.255
因特網域名
? ? ? ? 因特網客戶端和服務器互相通信時使用的是IP地址.然而,對于人們而言,大整數是很難記住的,所以因特網也定義了一組更加人性化的域名,以及一種將域名映射到IP地址的機制.---黑體字是原話
? ? ? ? ---解讀:域名的由來
? ? ? ? 域名集合形成一個層次結構
? ? ? ? 一旦一個組織得到一個二級域名,那么他可以在這個子域中創建任何新的域名.如cs.cmu.edu
?????????---解讀:創建一個網站至少需要二級域名.
DNS數據庫
? ? ? ? 因特網定義了域名集合和IP地址集合之間的映射.直到1988年,這個映射都是通過一個叫做HOSTS.TXT的文本文件來手工維護.從那以后,這個映射通過分布世界范圍內的數據庫DNS(Domain Name System,域名系統)來維護.
? ? ? ? DNS數據庫由上百萬的主機條目結構組成,其中每條定義了一組域名和一組IP地址之間的映射.從數學意義來講,可以認為每條主機條目就是一個域名和IP地址的等價類.
? ? ? ? ---解讀:條目類試設計
//不太可能設計
struct Entry{vector<string> domain_name;vector<string> IP_address;
}
? ? ? ? 域名系統包含有上百萬個Entry對象,可對其進行添加,查找和修改等操作.試試看著不太可能,同樣應選擇"層級"的數據結構---筆者前面帖子有闡述????????
//有可能設計
struct Com{string next_name;vector<string> IP_address;vector<Com> com;
}
? ? ? ? 查找算法:將域名按照"."隔開的字符串取出,每個字符串交給next_name做匹配,如果匹配成功,則IP_address是所需要的字符串集合---即上面的點分十進制串,再將其轉化成IP地址,可訪問對應服務器.
? ? ? ? 如果按照這個思路,需要確定一級域名的所有形式,即第一層域名必須只有com,edu,gov,org和net.然后分別寫出struct Edu,struct Gov,struct Org和struct Net
? ? ? ? 注意:能不能寫到一起設計個類?因為至少兩層域名才得到IP地址,比如csdn.net可以但是net不可以.所以類型設計的時候分開比較好.
域名和IP地址的對應
? ? ? ? 1>一一對應
? ? ? ? 一個域名對應一個IP地址
? ? ? ? 2>一對多
? ? ? ? 一個域名對應多個IP地址.這種場景比如一個大型網站,流量非常大,需要在全球范圍內多個國家架設多個服務器來應對,或者應對其他復雜情形.
? ? ? ? 3>多對一
? ? ? ? 多個域名對應一個IP地址
? ? ? ? ---解讀:按照前面條目類型的說法:主機條目就是一個域名和IP地址的等價類(黑體字是原話),也不用考慮那么多,幾百萬的數據量不是很大,搜索和添加的影響都不大,他的類型設計仍然按照一一對應關系.
因特網連接
? ? ? ?本書原話:?因特網客戶端和服務器通過連接發送和接收字節流來通信.連接是點對點的,全雙工的,可靠的.
? ? ? ? 連接由"地址:端口"表示.客戶端套接字地址由內核自動分配,服務器套接字地址中的端口通常是某個知名端口.
? ? ? ? 如圖,客戶端和服務器之間的連接由下列套接字對唯一確定了.
? ? ? ? (128.2.194.242:51213,208.216.181.15:80)
? ? ? ? ---解讀:因特網連接的規定,套接字對確定連接,也沒說怎么實現的,留待后面內容解讀.?