網絡編程
ISO七層模型 ——》網絡通信工作流程的標準化
應用層 : 提供用戶服務,具體功能由特定的程序而定
表示層 : 數據的壓縮優化,加密
會話層 : 建立應用級的連接,選擇傳輸服務
傳輸層 : 提供不同的傳輸服務。流量控制
網絡層 : 路由選擇,網絡互連
鏈路層 : 進行數據轉換,具體消息的發送,鏈路連接
物理層 : 物理硬件,接口設定,網卡路由交換機等
cookie
高內聚:模塊功能儘可能單一,不要摻雜
低耦合:模塊之間儘可能減少關聯和影響
OSI七層模型的優點:
- 將流程標準化
- 降低了模塊的耦合度,是每一個部分單獨開發,單獨工作
但是實際工作中,我們使用的是四層模型
應用層:應用層,表示層,會話層
傳輸層
網絡層
物理鏈路層
數據傳輸流程
- 發送端由應用層到物理層逐層添加信息頭(首部),最終在物理層發送。
- 中間經過節點(交換機,路由器等)轉發,發送到接收端
- 在接收端根據發送端的每個信息頭進行解析,最終消息到應用層展示給用戶。
應用層 : TFTP HTTP DNS SMTP
傳輸層 : TCP UDP
網絡層 : IP
物理層 : IEEE
傳輸層服
面向連接的傳輸服務——> tcp
傳輸特徵 : 提供可靠的數據傳輸,可靠性指數據傳輸過程中無丟失,無失序,無差錯,無重複
實現手段:數據傳輸斷開前都需要進行傳輸和斷開的確認
三次握手 : tcp傳輸在數據傳輸前建立連接的過程
- 客戶端向服務器發送連接請求
- 服務器收到請求後,恢復確認消息,表示允許連接
- 客戶端收到服務器恢復,進行最終標誌發送確認連接
四次揮手 : tcp傳輸在連接斷開前進行斷開確認的過程
- 主動發發送報文告知被動方要斷開連接
- 被動方收到請求後立即返回報文告知已經準備斷開
- 被動方準備就緒後再次發送報文告知可以斷開
- 主動方發送消息,確認最終斷開
應用情況 : 適用於傳輸較大的文件,網絡情況良好,需要保證傳輸可靠性的情況。
比如: 網頁的獲取,文件下載,郵件傳輸,登錄註冊
面向無連接的傳輸服務——> udp
傳輸特點 : 不保證傳輸的可靠性,傳輸過程沒有連接和斷開的流程,數據收發自由。
使用情況 : 網絡情況較差,對傳輸可靠性要求不高,需要提升傳輸效率。不便連接,需要靈活收發消息。
比如:網絡視頻,羣聊,廣播發送
socket套接字
套接字分類:
- 流式套接字(SOCK_STREAM): 傳輸層基於tcp協議
- 數據報套接字(SOCK_DGRAM): 傳輸層基於udp協議
*面向連接的傳輸–tcp協議–可靠地–流式套接字
*面向無連接傳輸–udp協議–不可靠–數據報套接字
tcp編程規範
import socket
1. 創建套接字
sockfd = socket.socket(socket_family = AF_INET,socket_type = SOCK_STREAM,proto = 0)
功能 : 創建套接字
參數 : socket_family : 選擇地址族類型 AF_INET(IPV4)
socket_type : 套接字類型 SOCK_STREAM 流式
SOCK_DGRAM 數據報
proto : 選擇子協議類型 通常爲0
返回值 : 返回套接字對象
2. 綁定服務端地址
sockfd.bind(addr)
功能 : 綁定IP地址
參數 : 元組 (ip,port)
localhost 可以被本機用 127.0.0.1
127.0.0.1 同上
192.168.205.127 可以被所有人用192.168.205.127訪問
0.0.0.0 可以被所有人用192.168.205.127訪問,也可被自己用127.0.0.1訪問
3. 設置監聽套接字
sockfd.listen(n)
功能:將套接字設置爲監聽套接字,創建監聽隊列
參數:n 表示監聽隊列大小
* 一個監聽套接字可以連接多個客戶端套接字
4. 等待處理客戶端連接請求
connfd,addr = sockfd.accept()
功能 : 阻塞等待處理客戶端連接
返回值: connfd 客戶端連接套接字
addr 連接的客戶端地址
* 阻塞函數 : 程序運行過程中遇到阻塞函數則暫停運行,直到某種阻塞條件達成再繼續運行。
5. 消息收發
data = connfd.recv(buffersize)
功能 : 接收對應客戶端消息
參數 : 一次最多接收多少字節
返回值 : 接收到的內容
* 如果沒有消息則會阻塞
n = connfd.send(data)
功能 : 發送消息給對應客戶端
參數 : 要發送的內容,必須是bytes格式
返回值 : 返回實際發送消息的大小
6. 關閉套接字
sockfd.close()
功能: 關閉套接字
tcp客戶端
1. 創建套接字
* 必須相同類型的套接字才能通信
2. 建立連接
sockfd.connect(servr_addr)
功能 : 建立連接
參數 : 元組, 服務端地址
3. 消息收發
send/recv
* 消息收發要和服務端配合,避免兩邊都出現recv阻塞
4. 關閉套接字
tcp服務端流程
socket() ---> bind() ---> listen() ---> accept()--->
recv/send ---> close()
客戶端
socket() ---> connect() ---> send/recv --->close()
注意:send和recv實際上是和緩衝區進行交互,發送緩衝區滿時就無法發送,接收緩衝區滿時recv才阻塞
tcp傳輸存在的問題:
- tcp粘包問題,因爲tcp套接字以字節流方式傳輸,沒有消息邊界
- 當連接的另一端退出時,再試圖send發送就會產生BrokenPipeError,所以需要try保護
TCP粘包的解決方法:
- 人爲增加消息邊界
- 發送數據結構體
- 協調收發速度,每次發送後都預留接收時間
udp編程規範
1. 創建數據報套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
2. 綁定地址
sockfd.bind(addr)
3. 消息的收發
data,addr = sockfd.recvfrom(buffersize)
功能 : 接收UDP消息
參數 : 每次最多接收多大的消息
返回值:data 接收到的數據
addr 消息發送端的地址
* 一次接收一個數據報,如果數據報大小大於buffersize則會丟失部分消息
sockfd.sendto(data,addr)
功能 : 發送udp消息
參數 : data 發送的消息 bytes格式
addr 目標地址
返回值: 發送的字節數
4. 關閉套接字
sockfd.close()
udp客戶端
1. 創建套接字
socket(AF_INET,SOCK_DGRAM)
2. 消息收發
recvfrom/sendto
3. 關閉套接字
close()
cookie
1. sys.argv 屬性
功能 : 獲取命令行參數,得到一個列表
tcp套接字編程和udp套接字編程區別
- 流式套接字使用字節流的方式傳輸,數據報套接字以數據報形式傳輸數據
- tcp會有粘包現象,udp有消息邊界不會形成粘包
- tcp 可以保障數據傳輸完整性,udp則不保證
- tcp 需要進行listen accept 操作,udp不需要
- tcp收發消息使用新的套接字,recv send。udp使用recvfrom,sendto