網絡編程(part10)--socket套接字編程之UDP套接字

鄙人學習筆記



UDP套接字編程

服務端流程

  1. 創建數據報套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
  1. 綁定地址
sockfd.bind(addr)

備註:作爲服務端,必然要綁定地址的。

  1. 消息收發
data,addr = sockfd.recvfrom(buffersize)
功能: 接收UDP消息
參數: 每次最多接收多少字節
返回值:
		 data  接收到的內容
	     addr  消息發送方地址
n = sockfd.sendto(data,addr)
功能: 發送UDP消息
參數: 
		data  發送的內容 bytes格式
	    addr  目標地址
返回值:發送的字節數
備註:由於UDP沒有創建連接,所以沒有一個專門的連接套接字對象(一發送就知道發送給誰),所以我們需要指明目標地址。

備註:UDP不需要創建連接。

  1. 關閉套接字
sockfd.close()

舉個例子

代碼:

from socket import *

#創建數據報套接字
sockfd = socket(AF_INET, SOCK_DGRAM)

#綁定地址
server_addr = ('127.0.0.1',8888)
sockfd.bind(server_addr)

#收發消息
while True:
    data,addr = sockfd.recvfrom(1024)
    print("收到的消息:",data.decode())
    sockfd.sendto(b"Thanks",addr)

#關閉套接字
sockfd.close()

客戶端流程

  1. 創建數據報套接字
  2. 收發消息
  3. 關閉套接字

備註:依然要注意,客戶端與服務端的收發順序。若服務端先收後發,則客戶端先發後收。

舉個例子

服務端代碼:

客戶端代碼:

運行服務端:

運行客戶端,併發送消息:

查看服務端:

備註:由於是UDP協議,所以相當”自由”,可以同時接收多個客戶端發來的消息。在這裏就不演示了。

這裏,我們再更改一下服務端的recvfrom的參數,來控制一下每次最多能接收的字節數(客戶端代碼不變)。

服務端代碼:

用客戶端發送hello world:

客戶端接收到服務端的消息:

服務端輸出:

得到5個字節。

我們再用客戶端發送nihao:

服務端輸出:

咦?這是咋回事?咋和TCP的不太一樣?
…好吧,第一次發送的【hello world】的後面的【 world】丟失了。這是提供不可靠傳輸服務的體現。但這個是合理的,比如,客戶端A和客戶端B都向服務端send()消息,UDP協議的不可靠傳輸雖然可能會丟失消息,但不會使客戶端A發送過來的消息,顯示在客戶端B發送的消息裏面。這樣,寧願丟失消息,也不能導致混亂。
所以,UDP套接字傳輸中,如果一次接收消息接收不完(超過最多能接收的字節數),則會把剩下的消息(超過指定字節數的部分)丟棄。

同時,UDP數據傳輸是不存在粘包的問題,因爲它存在消息邊界。就像我們之前形容的那樣,TCP傳輸是水流,UDP傳輸是水瓶。UDP傳輸,是一個一個”數據報”傳輸的,它的消息之間是存在邊界的。

TCP套接字和UDP套接字編程區別

①流式套接字是以字節流方式傳輸數據;數據報套接字以數據報形式傳輸
②TCP套接字會有粘包;UDP套接字有消息邊界,不會粘包
③TCP套接字保證消息的完整性;UDP套接字則不能
④TCP套接字依賴listen、accept建立連接才能收發消息;UDP套接字則不需要
⑤TCP套接字使用send、recv收發消息;UDP套接字使用sendto、recvfrom

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章