1. 程式人生 > >python3網路程式設計01

python3網路程式設計01

網路程式設計
網路目的 : 資料傳輸
ISO(國際標準化組織)
OSI七層模型 ----》 網路通訊的標準化流程
應用層 : 提供使用者服務, 具體的內容由特定的程式規定
表示層 : 提供資料的加密和壓縮優化
會話層 : 確定建立應用級的連線,選擇傳輸服務
傳輸層 : 提供不同的資料傳輸服務,進行流量控制
網路層 : 路由選擇,網路互聯
鏈路層 : 提供鏈路交換,具體訊息的傳送
物理層 : 物理硬體,介面,網絡卡的規定

四層模型

應用層
傳輸層
網路層
物理鏈路層

五層模型(TCP/IP模型)

應用層 (應用層 表示層 會話層)
傳輸層
網路層
鏈路層
物理層

OSI模型優點 : 將功能分開,降低網路傳輸中的耦合度。使開發流程更加清晰,每部分各司其職

高內聚 : 每個模組功能儘量單一,不會多個功能摻雜
低耦合 : 儘量降低每個模組之間的關聯性

要求 : 能夠順序說出七層模型 五層模型
知道每一層幹什麼事情
理解訊息傳輸流程
資料傳輸流程
1 傳送端由應用層到物理層逐級新增資訊頭(首部),最終在物理層傳送
2中間經過節點(交換機,路由器)轉發傳送到接收端
3 在接受端根據傳送端的每個資訊頭進行解析,最終訊息到應用層展示給使用者

網路協議:在網路通訊中協議各方必須遵守的規定。如建立什麼連線,訊息結構如何解析等

應用層 : TFTP HTTP DNS SMTP
傳輸層 : TCP UDP
網路層 : IP
物理層 : IEEE

網路相關概念

網路主機 : 在網路上確定一臺主機 Host
本地使用 : ‘localhost’ 127.0.0.1
網路地址 : ‘0.0.0.0’ ‘172.60.50.54’ (本機網路IP)
檢視本機IP地址:ifconfig (linux)
ipconfig (windows)

ipython3 進入互動模式

通過計算機名獲取匹配的IP
In [5]: socket.gethostbyname(‘tedu’)
Out[5]: ‘127.0.1.1’

In [6]: socket.gethostbyname(‘localhost’)
Out[6]: ‘127.0.0.1’

獲取本機的計算機名
In [7]: socket.gethostname()
Out[7]: ‘tedu’

IP地址
網路上確定一臺主機的地址
IPv4: 點分十進位制 比如 192.168.1.3 0–255
IPv6 128位

網路連線測試
ping 172.60.50.180

特殊IP
127.0.0.1 本地測試IP
0.0.0.0 自動使用本地可用網絡卡IP
192.168.1.0 代表當前網段
192.168.1.1 通常為閘道器地址
192.168.1.255 廣播地址

通過地址獲取主機網路資訊
In [2]: socket.gethostbyaddr(‘www.baidu.com’)
Out[2]: (‘127.0.0.1’, [], [‘119.75.213.61’])
主機 別名 IP地址

IP地址轉換為十六進位制表達
In [4]: socket.inet_aton(‘192.168.1.2’)
Out[4]: b’\xc0\xa8\x01\x02’

In [5]: socket.inet_ntoa( b’\xc0\xa8\x01\x02’)
Out[5]: ‘192.168.1.2’
域名:網路伺服器地址在網路上的名稱
埠號: 埠號是網路地址的一部分,用於區分一個網路主機上的網路應用
*在一個系統中每個網路應用監聽不同的埠,以獲取對應埠傳遞的資訊
取值範圍 : 1----65535
1-255 一些通用埠 (眾所周知的程式佔用)
256 --1023 系統埠
1024 – 65535 自用埠 >10000
獲取應用程式埠
In [2]: socket.getservbyname(‘mysql’)
Out[2]: 3306
網路位元組序:資料在網路中的傳輸格式
傳輸層服務
面向連線的傳輸服務
基於tcp協議的資料傳輸
傳輸特徵:可靠的資料傳輸
可靠性 : 資料在傳輸中,無失序 無差錯 無丟失 無重複
實現手段:在資料傳輸前和傳輸結束後需要建立連線和斷開連線
三次握手 : 在面向連線的傳輸服務中建立連線的過程

  1. 客戶端向伺服器傳送連線請求
  2. 伺服器接受到請求進行確認,返回確認報文
  3. 客戶端收到伺服器回覆最終確認連線
    四次揮手 : 在面向連線的傳輸服務站斷開連線的過程
  4. 主動方傳送報文,告知被動方要斷開連線
  5. 被動方回覆報文,表示已經接收到請求,準備斷開
  6. 被動方再次傳送報文,表示準備處理就緒,可以斷開
  7. 主動發發送確認報文,斷開連線
    應用情況 : 適用於傳輸較大的內容或檔案,網路良好,需要保證傳輸可靠性的情況
    e.g. 聊天資訊 檔案的上傳下載, 郵件處理
    網頁獲取
    面向無連線的傳輸服務----udp協議
    傳輸特點:
    不保證傳輸的可靠性
    沒有連線和斷開的過程
    資料的收發比較自由
    適用情況 : 網路情況可能產生丟包,對傳輸可靠性要求低
    e.g. : 網路視訊, 群聊,廣播等
    要求:
  8. 理解三次握手和四次揮手,能夠描述過程
  9. 知道tcp傳輸和udp傳輸的區別
    3,七層模型osi

socket 套接字程式設計
目的 : 通過程式語言提供的套接字程式設計介面,可以更簡單的完成基於tcp和udp的程式設計
套接字 : 完成上述目標的一種程式設計手段
套接字類別
流式套接字(SOCK_STREAM):傳輸層基於tcp的協議通訊
面向連線可靠的傳輸 tcp的傳輸 流式套接字
資料報套接字(SOCK_DGRAM): 傳輸層基於udp協議傳輸
面向無連線不可靠的傳輸 udp的傳輸 資料報套接字
底層套接字 (SOCK_RAM): 訪問底層協議套接字
TCP的服務端
import socket

  1. 建立套接字
    socket.socket(sock_family = AF_INET,
    sock_type = SOCK_STREAM,
    proto = 0)
    功能 : 建立套接字
    引數 : sock_family 地址族型別 AF_INET ipv4網路通訊
    sock_type 套接字型別 SOCK_STREAM 流式
    SOCK_DGRAM 資料報
    proto 通常為0 選定子協議型別
    返回值 :返回套接字物件
  2. 繫結地址
    sockfd.bind(addr)
    功能 : 繫結地址
    引數 : addr —》 元組 (ip,port) (‘0.0.0.0’,1234)
  3. 設定監聽套接字
    sockfd.listen(n)
    功能: 將套接字設定為監聽套接字,建立監聽佇列
    引數: 監聽佇列大小
  • 一個監聽套接字可以連線多個客戶端
  1. 等待接受客戶端連線
    connfd,addr = sockfd.accept()
    功能 : 阻塞等待處理客戶端連線
    返回值 : connfd 新的套接字,用於和客戶端通訊
    addr 連線的客戶端的地址 (ip,port)
  • 阻塞函式 : 當程式執行到阻塞函式位置,如果某種條件沒有達成則暫停程式執行,知道條件達成結束阻塞
  1. 訊息的收發
    data = connfd.recv(buffersize)
    功能 : 接受訊息
    引數 : 一次接受訊息的大小位元組
    返回值 : 返回接受到的內容
    n = connfd.send(data)
    功能 : 傳送訊息給對應客戶端
    引數 : 要傳送的內容,(bytes格式)
    返回值 : 返回實際傳送的位元組數
  2. 關閉套接字
    sockfd.close()
  • telnet ip port
    客戶端
  1. 建立套接字 (和服務端套接字型別相同)
  2. 發起連線
    connect(addr)
    功能 : 向服務端發起連線
    引數 : 服務端地址 元組
  3. 訊息收發
  4. 關閉套接字
    ocket函式 描述
    服務端socket函式
    s.bind(address) 將套接字繫結到地址, 在AF_INET下,以元組(host,port)的形式表示地址.
    s.listen(backlog) 開始監聽TCP傳入連線。backlog指定在拒絕連線之前,作業系統可以掛起的最大連線數量。該值至少為1,大部分應用程式設為5就可以了。
    s.accept() 接受TCP連線並返回(conn,address),其中conn是新的套接字物件,可以用來接收和傳送資料。address是連線客戶端的地址。
    客戶端socket函式
    s.connect(address) 連線到address處的套接字。一般address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。
    s.connect_ex(adddress) 功能與connect(address)相同,但是成功返回0,失敗返回errno的值。
    公共socket函式
    s.recv(bufsize[,flag]) 接受TCP套接字的資料。資料以字串形式返回,bufsize指定要接收的最大資料量。flag提供有關訊息的其他資訊,通常可以忽略。
    s.send(string[,flag]) 傳送TCP資料。將string中的資料傳送到連線的套接字。返回值是要傳送的位元組數量,該數量可能小於string的位元組大小。
    s.sendall(string[,flag]) 完整發送TCP資料。將string中的資料傳送到連線的套接字,但在返回之前會嘗試傳送所有資料。成功返回None,失敗則丟擲異常。
    s.recvfrom(bufsize[.flag]) 接受UDP套接字的資料。與recv()類似,但返回值是(data,address)。其中data是包含接收資料的字串,address是傳送資料的套接字地址。
    s.sendto(string[,flag],address) 傳送UDP資料。將資料傳送到套接字,address是形式為(ipaddr,port)的元組,指定遠端地址。返回值是傳送的位元組數。
    s.close() 關閉套接字。
    s.getpeername() 返回連線套接字的遠端地址。返回值通常是元組(ipaddr,port)。
    s.getsockname() 返回套接字自己的地址。通常是一個元組(ipaddr,port)
    s.setsockopt(level,optname,value) 設定給定套接字選項的值。
    s.getsockopt(level,optname[.buflen]) 返回套接字選項的值。
    s.settimeout(timeout) 設定套接字操作的超時期,timeout是一個浮點數,單位是秒。值為None表示沒有超時期。一般,超時期應該在剛建立套接字時設定,因為它們可能用於連線的操作(如connect())
    s.gettimeout() 返回當前超時期的值,單位是秒,如果沒有設定超時期,則返回None。
    s.fileno() 返回套接字的檔案描述符。
    s.setblocking(flag) 如果flag為0,則將套接字設為非阻塞模式,否則將套接字設為阻塞模式(預設值)。非阻塞模式下,如果呼叫recv()沒有發現任何資料,或send()呼叫無法立即傳送資料,那麼將引起socket.error異常。
    s.makefile() 建立一個與該套接字相關連的檔案