1. 廖雪峰的官方網(wǎng)站
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000
2. Python快速教程
http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html
3. python 幫助
發(fā)送端:程序員編寫的應(yīng)用程序通過(guò)socket 函數(shù)庫(kù)的使用, 比如調(diào)sendto 或者send或者write , 這些函數(shù)在操作系統(tǒng)的用戶態(tài)空間,進(jìn)入操作系統(tǒng)的系統(tǒng)調(diào)用,調(diào)操作系統(tǒng)的sys_xxx 函數(shù),進(jìn)入操作系統(tǒng)的內(nèi)核態(tài)。
內(nèi)核態(tài)的網(wǎng)絡(luò)子系統(tǒng)(專門處理網(wǎng)卡、TCPIP協(xié)議的代碼), sys_sendto 判斷 是UDP還是TCP,如果是TCP,則調(diào) TCP_output 函數(shù),TCP_output負(fù)責(zé)填寫TCP首部的數(shù)據(jù),比如發(fā)送方的端口號(hào)和接收方的端口號(hào)、以及校驗(yàn)和(簡(jiǎn)單校驗(yàn),防止數(shù)據(jù)錯(cuò)誤)。
緊接著進(jìn)入IP層處理,調(diào)IP_output,查找路由(因?yàn)樵O(shè)備可能有多個(gè)網(wǎng)卡, 那怎么選擇? 根據(jù)目的IP地址來(lái)選路,類似于查地圖,找到哪個(gè)網(wǎng)卡), IP_output 填寫發(fā)送者的IP地址和接收者的IP地址信息。
IP層首部按固定格式填好之后,那么就進(jìn)入鏈路層(由物理層所決定,早起有的設(shè)備并沒(méi)有網(wǎng)卡,有的是直連的電話線或者串口等設(shè)備, 而網(wǎng)卡的設(shè)備識(shí)別ID是MAC地址, 6個(gè)字節(jié)。)
不同的鏈路層處理函數(shù)是不同的,如果是網(wǎng)卡,則是ethernet_output, 鏈路層的處理則是需要填寫自己的MAC地址和對(duì)方的MAC地址。 對(duì)方的MAC地址從哪里來(lái)?后面會(huì)講到。
鏈路層獲取到對(duì)方的MAC地址后,就把報(bào)文按固定格式填好,這個(gè)時(shí)候,所有的數(shù)據(jù)都按固定格式組裝完畢, 調(diào)網(wǎng)卡的驅(qū)動(dòng)程序的函數(shù) physic_send 發(fā)送(會(huì)觸發(fā)軟中斷或者加入隊(duì)列,寫一個(gè)消息,CPU后續(xù)從網(wǎng)卡獲取數(shù)據(jù)發(fā)送出去。)
接收端:
接收端網(wǎng)卡收到數(shù)據(jù)后,觸發(fā)了中斷, 報(bào)文的內(nèi)容被寫入一個(gè)隊(duì)列中,觸發(fā)一個(gè)軟中斷, 操作系統(tǒng)的內(nèi)核線程會(huì)去讀取隊(duì)列中的數(shù)據(jù)。讀到數(shù)據(jù)后,先解析是以太網(wǎng)的格式還是其他物理設(shè)備的格式。 以太網(wǎng) 的首部是14個(gè)字節(jié)(目的MAC是自己網(wǎng)卡的,報(bào)文才允許接收, 廣播報(bào)文也默認(rèn)會(huì)接收)
內(nèi)核線程調(diào)ethernet_input函數(shù)處理,如果是IP報(bào)文,則調(diào) ip_input函數(shù),進(jìn)行IP首部報(bào)文正確性檢查,如果目的IP地址屬于自己某個(gè)網(wǎng)卡的,則是屬于自己設(shè)備的報(bào)文,如果不是,要轉(zhuǎn)給其他設(shè)備(類似于路由器)(實(shí)際情況,判斷報(bào)文是不是自己設(shè)備,不是根據(jù)IP地址,而是根據(jù)路由表,后續(xù)再講)
IP_input 檢查報(bào)文中的 8位協(xié)議號(hào) 信息,如果是TCP 就調(diào)tcp_input函數(shù)處理,如果是udp,則調(diào)udp_input函數(shù)處理,如果是ping報(bào)文(準(zhǔn)備叫法是icmp),則調(diào)icmp_input函數(shù)處理。
最后tcp_input或者udp_input講報(bào)文入了tcp或者udp的數(shù)據(jù)隊(duì)列中,等程序員寫的socket程序 調(diào)recv或者recvfrom函數(shù)把數(shù)據(jù)讀走,繼續(xù)用于自己的數(shù)據(jù)解析,如,如果是HTTP報(bào)文,則進(jìn)行http報(bào)文解析處理。
2.1.2 Ping 的原理說(shuō)明Ping 是一個(gè)應(yīng)用程序,是通過(guò)socket 編程實(shí)現(xiàn)的, 通過(guò)創(chuàng)建一個(gè)raw socket。
socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
通過(guò)代碼 構(gòu)造IP首部、ICMP首部,將報(bào)文發(fā)送出去。
ICMP 請(qǐng)求 報(bào)文 8位類型和8位代碼是8和0
而ping的應(yīng)答報(bào)文 的type code是0和0
舉例 PC1 192.168.2.1 執(zhí)行ping 的應(yīng)用程序,發(fā)送報(bào)文給 PC3 192.168.2.3
而實(shí)際上PC3 192.168.2.3上是沒(méi)有啟動(dòng)應(yīng)用程序的,但是結(jié)果能ping 通? 原因是?
PC3 中 操作系統(tǒng)的內(nèi)核收到ICMP 請(qǐng)求報(bào)文后, 直接進(jìn)行了ICMP應(yīng)答,即這個(gè)報(bào)文不會(huì)到達(dá)應(yīng)用程序(因?yàn)椴恍枰??只需要知道這個(gè)IP地址真實(shí)存在就OK了) ,但是這個(gè)應(yīng)答報(bào)文需要 送給PC1 的應(yīng)用程序? 為什么? 因?yàn)閜ing 是應(yīng)用程序發(fā)送出來(lái)的,那么應(yīng)用程序必然需要知道到底是成功還是失敗或者超時(shí)了。
打開(kāi) wireshark ,選擇真實(shí)的物理網(wǎng)卡
鼠標(biāo)選擇報(bào)文某個(gè)字段, 右鍵 選擇 apply as filter
可以選擇性報(bào)文,
同時(shí)也可以 && tcp 或者&& http 選擇報(bào)文類型抓包
1. 寬帶辦理
家庭A和家庭B 屬于一個(gè)小區(qū)的兩家用戶 ,分別辦理了寬帶。
家庭A的路由器和家庭B的路由器 通電后,會(huì)發(fā)送廣播報(bào)文(這個(gè)時(shí)候還沒(méi)有IP地址) 發(fā)送給電信的交換機(jī)(交換機(jī)轉(zhuǎn)給電信路由器) ,電信路由器對(duì) 家庭A/B路由器響應(yīng), 家庭A/B 將用戶名和密碼填寫到報(bào)文里面, 電信路由器收到報(bào)文后,根據(jù)密碼進(jìn)行判斷,如果在自己的用戶名列表且密碼正確,則給每家分配一個(gè)IP地址,IP地址是201.1.1.10和201.1.1.20 ,同時(shí)在報(bào)文里面將DNS服務(wù)器 114.114.114.11的地址帶給A/B
結(jié)合實(shí)際家里的路由器舉例:
在瀏覽器輸入192.168.1.1 可以查看自己家路由器的信息
10.68.166.75 就是電信路由器給家庭分配的IP地址;
10.64.0.10 和10.64.0.100 是電信路由器在分配IP地址的過(guò)程中攜帶回來(lái)的DNS服務(wù)器IP, 相當(dāng)于組網(wǎng)圖中的114.114.114.114
2. 手機(jī)和電腦的IP地址從哪里來(lái)的?
手機(jī)和電腦的IP的地址是從自己的路由器分配的(當(dāng)然也可以手動(dòng)配置IP地址,但是管理起來(lái)比較復(fù)雜),采用的是DHCP 自動(dòng)分配IP地址。 比如,查看自己的電腦
點(diǎn) 開(kāi)始 --à運(yùn)行
輸入 ipconfig /all
備注: 通常情況下 自己家路由器的DNS server 也是192.168.1.1 ,這里的114.114.114.114是我修改的,有時(shí)候網(wǎng)頁(yè)訪問(wèn)出現(xiàn)問(wèn)題,和DNS 有關(guān)。
手機(jī)和電腦開(kāi)機(jī)后,通過(guò)DHCP協(xié)議(后續(xù)再講)從家庭路由器 192.168.1.1 中獲取IP地址和DNS服務(wù)器的IP地址,得到192.168.1.10/192.168.1.20,并得到DNS 服務(wù)器192.168.1.1
3. DNS獲取
手機(jī) 開(kāi)始上網(wǎng) 瀏覽器輸入www.google.com
互聯(lián)網(wǎng)訪問(wèn)時(shí)基于IP地址的,這個(gè)時(shí)候需要獲取www.google.com對(duì)應(yīng)的真實(shí)IP地址。
手機(jī)檢查本地系統(tǒng)DNS緩存有沒(méi)有g(shù)oogle的歷史記錄,如果沒(méi)有,就向 自己的家庭路由器 192.168.1.1 這個(gè)IP地址發(fā)送DNS 請(qǐng)求查詢(請(qǐng)告訴我 google的IP) , 家庭路由器 看看自己的DNS緩存有沒(méi)有,如果沒(méi)有,就向電信的DNS服務(wù)器 114.114.114.114 查詢(請(qǐng)告訴我 google的IP), 如果電信DNS也沒(méi)有,即向國(guó)際頂級(jí)DNS 服務(wù)器8.8.8.8(備注: 8.8.8.8實(shí)際是google的DNS服務(wù)器,這里只是舉例), 只要開(kāi)通了DNS注冊(cè),交錢的國(guó)際企業(yè)在 頂級(jí)域名是有記錄的(除非只在某個(gè)范圍內(nèi)生效)。 最終手機(jī)就可以獲取到www.google.com IP地址是圖中9.9.9.20。
那么手機(jī)就可以將 192.168.1.1 發(fā)給 9.9.9.20 的http報(bào)文發(fā)送出去。
4 .報(bào)文通過(guò)路由器轉(zhuǎn)發(fā)
手機(jī) 訪問(wèn) 9.9.9.20(google)的http報(bào)文 ,
手機(jī) à 家庭路由器
源IP地址是192.168.1.10 ,目的IP地址是9.9.9.20 ; 這里有個(gè)問(wèn)題: 別人家也有一個(gè)192.168.1.10,那么google的服務(wù)器怎么知道是誰(shuí)家的 192.168.1.10?
數(shù)據(jù)在互聯(lián)網(wǎng)上傳輸,肯定是需要一個(gè)唯一的IP地址,那么對(duì)每家來(lái)說(shuō),唯一的IP地址是電信分配的。也就是說(shuō),每家只能用自己的IP地址作為源IP地址。
那么我家里有多臺(tái)手機(jī)和電腦,怎么辦?
手機(jī)1 192.168.1.10: 789 à 9.9.9.20: 80 被家庭路由器SNAT 成 201.1.1.10: 123à 9.9.9.20: 80
電腦1 192.168.1.20: 678 à 9.9.9.20: 80被家庭路由器SNAT 成 201.1.1.10: 124à 9.9.9.20: 80
也就是說(shuō),數(shù)據(jù)出了自己的路由器,整個(gè)過(guò)程源IP地址、目的IP地址、源端口號(hào)、目的端口號(hào)都是不變的,直到到達(dá)google, google返程 分別回給201.1.1.10:123和201.1.1.20:124
數(shù)據(jù)到達(dá)家庭路由器后,重新把目的IP地址換回192.168.1.10和192.168.1.20。最終完成數(shù)據(jù)的傳輸過(guò)程。
以太網(wǎng)是根據(jù)MAC地址識(shí)別的。
PC1 學(xué)習(xí)到了PC3 的MAC地址,才可以發(fā)送報(bào)文,否則無(wú)法ping通,比如把 PC3移除。
192.168.2.1 向 192.168.2.3 發(fā)送 ARP報(bào)文,根據(jù)ARP的報(bào)文格式
類型 0x0800表示 ARP報(bào)文 。
發(fā)送ARP請(qǐng)求,只知道 自己的MAC地址,自己的IP地址, 對(duì)方的IP地址,但是不知道對(duì)方的MAC地址。 相當(dāng)于 我要找人,這個(gè)人在我視線范圍,但是我不認(rèn)識(shí)他。那么我喊一下(廣播),讓所有的人都能聽(tīng)到。 目的MAC地址填 ff-ff-ff-ff-ff-ff 。
所有收到的人 判斷一下是不是自己的IP地址,如果是自己的IP地址,那么就單播應(yīng)答一下。
這樣一來(lái),雙方都能知道對(duì)方的MAC地址。 記錄到內(nèi)存里面。因?yàn)橄乱粋€(gè)使用的時(shí)候不需要重新發(fā)送報(bào)文,提高效率。 但是如果一直不再給對(duì)方發(fā)送數(shù)據(jù),也不知道對(duì)方還在不再。那么又存在浪費(fèi)內(nèi)存的情況。最好的方式是設(shè)置一個(gè)超時(shí)時(shí)間,默認(rèn)20分鐘。 如果20分鐘到了,再重新發(fā)送一次,如果能學(xué)習(xí)到,說(shuō)明還在,繼續(xù)保留這個(gè)表象。
在Windows7上 運(yùn)行 開(kāi)始 cmd 輸入 arp –a 可以觀察到這個(gè)表項(xiàng)
Hub組網(wǎng), PC1 ping PC3 ,在 PC2上可以抓到所有報(bào)文
但是把HUB換成交換機(jī), PC1 ping PC3, 在PC2上只能抓到ARP請(qǐng)求報(bào)文(確切說(shuō)是廣播報(bào)文)
為什么?
3.1.3 路由器組網(wǎng)下的ARP學(xué)習(xí)組網(wǎng)如圖,啟動(dòng)三個(gè)設(shè)備
雙擊 路由器
給路由器配置IP地址
<Huawei>sys
[Huawei]interface Ethernet 0/0/0
[Huawei-Ethernet0/0/0]ip address 192.168.1.1 24
[Huawei-Ethernet0/0/0]q
[Huawei]interface ethernet0/0/1
[Huawei-Ethernet0/0/1]ip address 192.168.2.1 24
在PC1 192.168.1.10 上ping PC2 192.168.2.20
如果沒(méi)有路由器, PC1和PC2是不同網(wǎng)段, 是ping 不通的。如果換成交換機(jī)或者HUB,也是ping 不通的。 跨網(wǎng)段必須需要一個(gè)路由器來(lái)轉(zhuǎn)發(fā)(備注:這里的交換機(jī)指二層交換機(jī),三層交換機(jī)具備路由器的特征,可以三層轉(zhuǎn)發(fā); 二層表示是同一個(gè)網(wǎng)段)
觀察,為什么PC1 沒(méi)有PC2的MAC地址? 而只有路由器192.168.1.1的MAC地址?
3.2 觀察windows 上的路由表3.3路由的選路過(guò)程Server.py
Client.py
聯(lián)系客服