網絡概述
理解
- 使用網絡能夠把多方鏈接在一起,然後可以進行數據傳遞
- 所謂的網絡編程就是,讓在不同的電腦上的軟件能夠進行數據傳遞,即進程之間的通信
tcp/ip簡介
1. 什麽是協議
有的說英語,有的說中文,有的說德語,說同一種語言的人可以交流,不同的語言之間就不行了
為了解決不同種族人之間的語言溝通障礙,現規定國際通用語言是英語,這就是一個規定,這就是協議
2. 計算機網絡溝通用什麽
現在的生活中,不同的計算機只需要能夠聯網(有線無線都可以)那麽就可以相互進行傳遞數據
那麽不同種類之間的計算機到底是怎麽進行數據傳遞的呢?
就像說不同語言的人溝通一樣,只要有一種大家都認可都遵守的協議即可,那麽這個計算機都遵守的網絡通信協議叫做TCP/IP協議
3. TCP/IP協議(族)
早期的計算機網絡,都是由各廠商自己規定一套協議,IBM、Apple和Microsoft都有各自的網絡協議,互不兼容
為了把全世界的所有不同類型的計算機都連接起來,就必須規定一套全球通用的協議,為了實現互聯網這個目標,互聯網協議簇(Internet Protocol Suite)就是通用協議標準。
因為互聯網協議包含了上百種協議標準,但是最重要的兩個協議是TCP和IP協議,所以,大家把互聯網的協議簡稱TCP/IP協議
常用的網絡協議如下圖所示:
說明:
網際層也稱為:網絡層
網絡接口層也稱為:鏈路層
端口
1. 什麽是端口
那麽TCP/IP協議中的端口指的是什麽呢?
端口就好一個房子的門,是出入這間房子的必經之路。
如果一個進程需要收發網絡數據,那麽就需要有這樣的端口
在linux系統中,端口可以有65536(2的16次方)個之多!
既然有這麽多,操作系統為了統一管理,所以進行了編號,這就是端口號
2. 端口號
端口是通過端口號來標記的,端口號只有整數,範圍是從0到65535
3. 端口是怎樣分配的
端口號不是隨意使用的,而是按照一定的規定進行分配。
端口的分類標準有好幾種,我們這裏不做詳細講解,只介紹一下知名端口和動態端口
3.1 知名端口(Well Known Ports)
知名端口是眾所周知的端口號,範圍從0到1023
80端口分配給HTTP服務 21端口分配給FTP服務
可以理解為,一些常用的功能使用的號碼是估計的,好比 電話號碼110、10086、10010一樣
一般情況下,如果一個程序需要使用知名端口的需要有root權限
3.2 動態端口(Dynamic Ports)
動態端口的範圍是從1024到65535
之所以稱為動態端口,是因為它一般不固定分配某種服務,而是動態分配。
動態分配是指當一個系統進程或應用程序進程需要網絡通信時,它向主機申請一個端口,主機從可用的端口號中分配一個供它使用。
當這個進程關閉時,同時也就釋放了所占用的端口號。
3.3 怎樣查看端口 ?
用“netstat -an”查看端口狀態
4. 小總結
端口有什麽用呢 ? 我們知道,一臺擁有IP地址的主機可以提供許多服務,比如HTTP(萬維網服務)、FTP(文件傳輸)、SMTP(電子郵件)等,這些服務完全可以通過1個IP地址來實現。那麽,主機是怎樣區分不同的網絡服務呢?顯然不能只靠IP地址,因為IP地址與網絡服務的關系是一對多的關系。實際上是通過“IP地址+端口號”來區分不同的服務的。 需要註意的是,端口並不是一一對應的。比如你的電腦作為客戶機訪問一臺WWW服務器時,WWW服務器使用“80”端口與你的電腦通信,但你的電腦則可能使用“3457”這樣的端口。
ip地址
IP就是用來標記地址用的。
ip地址的作用
ip地址:用來在網絡中標記一臺電腦的一串數字,比如192.168.1.1;在本地局域網上是惟一的。
ip地址的分類
每一個IP地址包括兩部分:網絡地址和主機地址
3.1 A類IP地址
一個A類IP地址由1字節的網絡地址和3字節主機地址組成,網絡地址的最高位必須是“0”,
地址範圍1.0.0.1-126.255.255.254
二進制表示為:00000001 00000000 00000000 00000001 - 01111110 11111111 11111111 11111110
可用的A類網絡有126個,每個網絡能容納1677214個主機
3.2 B類IP地址
一個B類IP地址由2個字節的網絡地址和2個字節的主機地址組成,網絡地址的最高位必須是“10”,
地址範圍128.1.0.1-191.255.255.254
二進制表示為:10000000 00000001 00000000 00000001 - 10111111 11111111 11111111 11111110
可用的B類網絡有16384個,每個網絡能容納65534主機
3.3 C類IP地址
一個C類IP地址由3字節的網絡地址和1字節的主機地址組成,網絡地址的最高位必須是“110”
範圍192.0.1.1-223.255.255.254
二進制表示為: 11000000 00000000 00000001 00000001 - 11011111 11111111 11111110 11111110
C類網絡可達2097152個,每個網絡能容納254個主機
3.4 D類地址用於多點廣播
D類IP地址第一個字節以“1110”開始,它是一個專門保留的地址。
它並不指向特定的網絡,目前這一類地址被用在多點廣播(Multicast)中
多點廣播地址用來一次尋址一組計算機
地址範圍224.0.0.1-239.255.255.254
3.5 E類IP地址
以“1111”開始,為將來使用保留
E類地址保留,僅作實驗和開發用
3.6 私有ip
在這麽多網絡IP中,國際規定有一部分IP地址是用於我們的局域網使用,也就
是屬於私網IP,不在公網中使用的,它們的範圍是:
10.0.0.0~10.255.255.255 172.16.0.0~172.31.255.255 192.168.0.0~192.168.255.255
3.7 註意
IP地址127.0.0.1~127.255.255.255用於回路測試,
如:127.0.0.1可以代表本機IP地址,用http://127.0.0.1
就可以測試本機中配置的Web服務器。
子網掩碼
要想理解什麽是子網掩碼,就不能不了解IP地址的構成。互聯網是由許多小型網絡構成的,每個網絡上都有許多主機,這樣便構成了一個有層次的結構。IP地址在設計時就考慮到地址分配的層次特點,將每個IP地址都分割成網絡號和主機號兩部分,以便於IP地址的尋址操作。
IP地址的網絡號和主機號各是多少位呢?
如果不指定,就不知道哪些位是網絡號、哪些是主機號,這就需要通過子網掩碼來實現。
子網掩碼不能單獨存在,它必須結合IP地址一起使用。
子網掩碼只有一個作用,就是將某個IP地址劃分成網絡地址和主機地址兩部分子網掩碼的設定必須遵循一定的規則。
與IP地址相同,子網掩碼的長度也是32位,
- 左邊是網絡位,用二進制數字“1”表示;
- 右邊是主機位,用二進制數字“0”表示。
假設IP地址為“192.168.1.1”子網掩碼為“255.255.255.0”。
其中,“1”有24個,代表與此相對應的IP地址左邊24位是網絡號; “0”有8個,代表與此相對應的IP地址右邊8位是主機號。 這樣,子網掩碼就確定了一個IP地址的32位二進制數字中哪些是網絡號、哪些是主機號。 這對於采用TCP/IP協議的網絡來說非常重要,只有通過子網掩碼,才能表明一臺主機所在的子網與其他子網的關系,使網絡正常工作。
最常用的兩種子網掩碼
子網掩碼是“255.255.255.0”的網絡:
最後面一個數字可以在0~255範圍內任意變化,因此可以提供256個IP地址。 但是實際可用的IP地址數量是256-2,即254個,因為主機號不能全是“0”或全是“1”。
主機號全為0,表示網絡號
主機號全為1,表示網絡廣播
註意
如果將子網掩碼設置過大,也就是說子網範圍擴大,那麽,根據子網尋徑規則,很可能發往和本地主機不在同一子網內的目標主機的數據,會因為錯誤的判斷而認為目標主機是在同一子網內,那麽,數據包將在本子網內循環,直到超時並拋棄,使數據不能正確到達目標主機,導致網絡傳輸錯誤;如果將子網掩碼設置得過小,那麽就會將本來屬於同一子網內的機器之間的通信當做是跨子網傳輸,數據包都交給缺省網關處理,這樣勢必增加缺省網關(文章下方有解釋)的負擔,造成網絡效率下降。因此,子網掩碼應該根據網絡的規模進行設置。如果一個網絡的規模不超過254臺電腦,采用“255.255.255.0”作為子網掩碼就可以了,現在大多數局域網都不會超過這個數字,因此“255.255.255.0”是最常用的IP地址子網掩碼;假如在一所大學具有1500多臺電腦,這種規模的局域網可以使用“255.255.0.0”。
socket簡介
1.本地的進程間通信(IPC)有很多種方式,例如
- 隊列
- 同步(互斥鎖、條件變量等)
以上通信方式都是在一臺機器上不同進程之間的通信方式,那麽問題來了
網絡中進程之間如何通信?
2. 網絡中進程之間如何通信
首要解決的問題是如何唯一標識一個進程,否則通信無從談起!
在本地可以通過進程PID來唯一標識一個進程,但是在網絡中這是行不通的。
其實TCP/IP協議族已經幫我們解決了這個問題,網絡層的“ip地址”可以唯一標識網絡中的主機,而傳輸層的“協議+端口”可以唯一標識主機中的應用程序(進程)。
這樣利用ip地址,協議,端口
就可以標識網絡的進程了,網絡中的進程通信就可以利用這個標誌與其它進程進行交互
3. 什麽是socket
socket(簡稱 套接字
) 是進程間通信的一種方式,它與其他進程間通信的一個主要不同是:
它能實現不同主機間的進程間通信,我們網絡上各種各樣的服務大多都是基於 Socket 來完成通信的
例如我們每天瀏覽網頁、QQ 聊天、收發 email 等等
4. 創建socket
在 Python 中 使用socket 模塊的函數 socket 就可以完成:
socket.socket(AddressFamily, Type)
說明:
函數 socket.socket 創建一個 socket,返回該 socket 的描述符,該函數帶有兩個參數:
- Address Family:可以選擇 AF_INET(用於 Internet 進程間通信) 或者 AF_UNIX(用於同一臺機器進程間通信),實際工作中常用AF_INET
- Type:套接字類型,可以是 SOCK_STREAM(流式套接字,主要用於 TCP 協議)或者 SOCK_DGRAM(數據報套接字,主要用於 UDP 協議)
創建一個tcp socket(tcp套接字)
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print ‘Socket Created‘
創建一個udp socket(udp套接字)
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print ‘Socket Created‘
UDP介紹
UDP --- 用戶數據報協議,是一個無連接的簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。
UDP是一種面向無連接的協議,每個數據報都是一個獨立的信息,包括完整的源地址或目的地址,它在網絡上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。
UDP特點:
UDP是面向無連接的通訊協議,UDP數據包括目的端口號和源端口號信息,由於通訊不需要連接,所以可以實現廣播發送。 UDP傳輸數據時有大小限制,每個被傳輸的數據報必須限定在64KB之內。 UDP是一個不可靠的協議,發送方所發送的數據報並不一定以相同的次序到達接收方。
【適用情況】
UDP是面向消息的協議,通信時不需要建立連接,數據的傳輸自然是不可靠的,UDP一般用於多點通信和實時的數據業務,比如
- 語音廣播
- 視頻
- TFTP(簡單文件傳送)
- SNMP(簡單網絡管理協議)
- RIP(路由信息協議,如報告股票市場,航空信息)
- DNS(域名解釋)
註重速度流暢
UDP操作簡單,而且僅需要較少的監護,因此通常用於局域網高可靠性的分散系統中client/server應用程序。例如視頻會議系統,並不要求音頻視頻數據絕對的正確,只要保證連貫性就可以了,這種情況下顯然使用UDP會更合理一些。
udp網絡程序-發送數據
創建一個udp客戶端程序的流程是簡單,具體步驟如下:
- 創建客戶端套接字
- 發送/接收數據
- 關閉套接字
代碼如下:
#coding=utf-8 from socket import * #1. 創建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 準備接收方的地址 sendAddr = (‘192.168.1.103‘, 8080) #3. 從鍵盤獲取數據 sendData = raw_input("請輸入要發送的數據:") #4. 發送數據到指定的電腦上 udpSocket.sendto(sendData, sendAddr) #5. 關閉套接字 udpSocket.close()
運行現象:
在Ubuntu中運行腳本:
在windows中運行“網絡調試助手”:
udp網絡程序-發送、接收數據
1. 創建udp網絡程序-接收數據
#coding=utf-8 from socket import * #1. 創建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 準備接收方的地址 sendAddr = (‘192.168.1.103‘, 8080) #3. 從鍵盤獲取數據 sendData = raw_input("請輸入要發送的數據:") #4. 發送數據到指定的電腦上 udpSocket.sendto(sendData, sendAddr) #5. 等待接收對方發送的數據 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字節數 #6. 顯示對方發送的數據 print(recvData) #7. 關閉套接字 udpSocket.close()
python腳本:
網絡調試助手截圖:
udp網絡程序-端口問題
會變的端口號
重新運行多次腳本,然後在“網絡調試助手”中,看到的現象如下:
說明:
- 每重新運行一次網絡程序,上圖中紅圈中的數字,不一樣的原因在於,這個數字標識這個網絡程序,當重新運行時,如果沒有確定到底用哪個,系統默認會隨機分配
- 記住一點:這個網絡程序在運行的過程中,這個就唯一標識這個程序,所以如果其他電腦上的網絡程序如果想要向此程序發送數據,那麽就需要向這個數字(即端口)標識的程序發送即可
udp綁定信息
1. 綁定信息
還記得在上一節課中,如果一個網絡程序在每次運行的時候端口是隨機變化的麽?
一般情況下,在一天電腦上運行的網絡程序有很多,而各自用的端口號很多情況下不知道,為了不與其他的網絡程序占用同一個端口號,往往在編程中,udp的端口號一般不綁定
但是如果需要做成一個服務器端的程序的話,是需要綁定的,想想看這又是為什麽呢?
如果報警電話每天都在變,想必世界就會亂了,所以一般服務性的程序,往往需要一個固定的端口號,這就是所謂的端口綁定
2. 綁定示例
#coding=utf-8 from socket import * #1. 創建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 綁定本地的相關信息,如果一個網絡程序不綁定,則系統會隨機分配 bindAddr = (‘‘, 7788) # ip地址和端口號,ip一般不用寫,表示本機的任何一個ip udpSocket.bind(bindAddr) #3. 等待接收對方發送的數據 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字節數 #4. 顯示接收到的數據 print recvData #5. 關閉套接字 udpSocket.close()
運行結果:
測試端
本程序
3. 總結
- 一個udp網絡程序,可以不綁定,此時操作系統會隨機進行分配一個端口,如果重新運行次程序端口可能會發生變化
- 一個udp網絡程序,也可以綁定信息(ip地址,端口號),如果綁定成功,那麽操作系統用這個端口號來進行區別收到的網絡數據是否是此進程的
udp網絡通信過程
udp應用:echo服務器
1. 運行現象
測試端
echo服務器端
2. 參考代碼
#coding=utf-8 from socket import * #1. 創建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 綁定本地的相關信息 bindAddr = (‘‘, 7788) # ip地址和端口號,ip一般不用寫,表示本機的任何一個ip udpSocket.bind(bindAddr) num = 1 while True: #3. 等待接收對方發送的數據 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字節數 #4. 將接收到的數據再發送給對方 udpSocket.sendto(recvData[0], recvData[1]) #5. 統計信息 print(‘已經將接收到的第%d個數據返回給對方,內容為:%s‘%(num,recvData[0])) num+=1 #5. 關閉套接字 udpSocket.close()
udp應用:聊天室
1. 運行現象
測試端
聊天室端
2. 參考代碼
#coding=utf-8 from socket import * from time import ctime #1. 創建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 綁定本地的相關信息 bindAddr = (‘‘, 7788) # ip地址和端口號,ip一般不用寫,表示本機的任何一個ip udpSocket.bind(bindAddr) while True: #3. 等待接收對方發送的數據 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字節數 #4. 打印信息 print(‘【%s】%s:%s‘%(ctime(),recvData[1][0],recvData[0])) #5. 關閉套接字 udpSocket.close()
udp總結
1. udp是TCP/IP協議族中的一種協議能夠完成不同機器上的程序間的數據通信
2. udp服務器、客戶端
- udp的服務器和客戶端的區分:往往是通過
請求服務
和提供服務
來進行區分 - 請求服務的一方稱為:客戶端
- 提供服務的一方稱為:服務器
3. udp綁定問題
- 一般情況下,服務器端,需要綁定端口,目的是為了讓其他的客戶端能夠正確發送到此進程
- 客戶端,一般不需要綁定,而是讓操作系統隨機分配,這樣就不會因為需要綁定的端口被占用而導致程序無法運行的情況
網絡概述