十一、網絡編程
一、網絡編程的目標
編寫一個C/S或B/S架構的基於網絡通信的軟件
C/S架構:客戶端---服務端
B/S架構:瀏覽器----服務端
學習socket編程就是要編寫客戶端軟件和服務端軟件,然後實現服務端和客戶端基於網絡通信
服務端特點:1、不間斷地提供服務;2、服務端要支持並發+高性能
二、網絡
網絡 = 物理連接介質 + 互聯網協議
互聯網協議分為OSI七層,或TCP/IP五層:
物理層:發送電信號-----基於二進制
數據鏈路層:ethernet以太網協議-----基於mac地址,在局域網內通信
網絡層:IP協議-----基於IP地址
傳輸層:TCP/UDP協議------基於端口(端口即應用程序與網卡關聯的編號)
應用層:HTTP、mail、ftp協議等
IP協議的作用:一個是為每一臺計算機分配IP地址,另一個是確定哪些地址在同一個子網絡
ARP協議:在同一個局域網內,根據IP地址獲取mac地址,操作系統自動轉換
路由協議:網關與網關之間的通信
TCP協議:TCP建立的是一個雙向連接,也叫流式協議
3次握手,建立客戶端和服務端的雙向通路
4次揮手,斷連接,服務端先發起斷連
mac地址 + IP地址 +端口就可以定位到世界上獨一無二的應用軟件;有了ARP協議,IP地址 + 端口就可以定位到世界上獨一無二的應用軟件。
三、socket編程
sockct(套接字)是位於應用層和傳輸層之間的一個抽象層,專門把傳輸層以下的協議封裝成接口給應用層使用。
套接字有兩種(或者稱為有兩個種族),分別是基於文件型的(AF_UNIX)和基於網絡型的(AF_INET)。
1、socket工作流程
服務端:
socket()---bind()---listen()---accept()---recv()---send()---close()
服務端先初始化socket,然後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。
服務端:
socket()---connect()---send()---recv()---close()
客戶端初始化一個socket,然後連接服務器(connect),如果連接成功,這時客戶端與服務端的連接就建立了。
客戶端發送數據請求(send),服務器端接收請求並處理請求(recv),然後把回應數據發送給客戶端(send),客戶端讀取數據(recv),最後關閉連接(close),一次交互結束。
bind() 綁定IP地址和端口。本地回環地址:127.0.0.1,端口:0到65535,其中0到1024是給系統用的
listen() 括號裏面的數字代表同一時間只能進來多少個請求
accept() 等待信息
reav(1024) 代表收消息,1024是一個最大的限制
send() 回消息
close() 關閉連接
2、粘包
只有TCP有粘包現象,UDP永遠不會粘包,因為TCP協議是面向流的協議,而UDP是面向消息的協議。
所謂粘包問題主要還是因為接收方不知道消息之間的界限,不知道一次性提取多少字節的數據所造成的。
兩種情況下會發生粘包:
1、發送端需要等緩沖區滿才發送出去,造成粘包(發送數據時間間隔很短,數據量很小,會合到一起,產生粘包)
2、接收方不及時接收緩沖區的包,造成多個包接收(客戶端發送了一段數據,服務端只收了一小部分,服務端下次再收的時候還是從緩沖區拿上次遺留的數據,產生粘包)
TCP是基於數據流的,於是收發的消息不能為空,這就需要在客戶端和服務端都添加空消息的處理機制
粘包的解決方法:
為字節流加上自定義固定長度報頭,報頭中包含字節流長度,然後一次send到對端,對端在接收時,先從緩存中取出定長的報頭,然後再取真實數據
使用struct模塊解決粘包
struct模塊的作用:
1、把整型數字轉成bytes類型
2、轉成的bytes是固定長度
可以把報頭做成字典,字典裏包含將要發送的真實數據的詳細信息,然後json序列化,然後用struck將序列化後的數據長度打包成4個字節(4個字節足夠用了)
發送時:
先發報頭長度
再編碼報頭內容然後發送
最後發真實內容
接收時:
先收報頭長度,用struct取出來
根據取出的長度收取報頭內容,然後解碼,反序列化
從反序列化的結果中取出待取數據的詳細信息,然後去取真實的數據內容
3、基於UDP協議通信的套接字
UDP是基於數據報的,一發對應一收
特點:無連接
優點:發送效率高,但有效傳輸的數據量最多為512bytes
缺點:不可靠(發送數據無須對方確認,容易丟包)
十一、網絡編程