Internet 協議集支持一個無連接的傳輸協議,該協議稱為用戶數據報協議(UDP,User Datagram Protocol)。
UDP 為應用程序提供了一種無需建立連接就可以發送封裝的 IP 數據包的方法。
udp網絡程序模型圖。
接下來,我們用 python 代碼實現udp數據的發送和接收。
一、udp網絡程序,發送數據
流程:
- 創建客戶端套接字
- 發送數據
- 關閉套接字
import socket
def main():
# 1.創建一個udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.准備接收方的地址
# 192.168.65.149 表示目的地ip
# 30000 表示目的地端口
udp_socket.sendto("hello".encode("utf-8"), ("192.168.65.149", 30000))
# 3.關閉套接字
udp_socket.close()
if __name__ == "__main__":
main()
sendto 的第一個參數需要一個字節類型,所以需要編碼一下,不能單單傳一個字符串。
我們為了驗證寫的程序是否正確,可以使用網絡調試助手來驗證。
在上面的例子中,網絡調試助手里的“本機主機地址”應該填寫作為服務方電腦的ip地址。我們這里在一台電腦上測試,所以寫了代碼里的ip地址。
但是大家要理解成是另一台服務器的電腦的ip。
端口就選擇一個號大一點的,不要占用主流端口。
二、udp網絡程序,接收數據
流程:
- 創建套接字
- 綁定本地自己的信息
- 接收數據
- 關閉套接字
接收數據最重要的一步,就是要綁定端口。
import socket
def main():
# 1.創建一個udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.綁定本地的相關信息,如果一個網絡程序不綁定,則系統會隨機分配
# 30000 表示本地的端口 ip一般不用寫
local_addr = ("", 30000)
udp_socket.bind(local_addr)
# 3. 等待接收對方發送的數據
recv_data = udp_socket.recvfrom(1024)
# 1024表示本次接收的最大字節數
# 6. 顯示對方發送的數據
# 接收到的數據recv_data是一個元組
# 第1個元素是對方發送的數據
# 第2個元素是對方的ip和端口
print(recv_data[0].decode('gbk'))
print(recv_data[1])
# 3.關閉套接字
udp_socket.close()
if __name__ == "__main__":
main()
將收到的數據解碼時要注意,和客戶端編碼的格式要一樣。
在選擇UDP作為傳輸協議時必須要謹慎。
在網絡質量令人十分不滿意的環境下,UDP協議數據包丟失會比較嚴重。
但是由於UDP的特性:它不屬於連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通數據在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。
比如我們聊天用的ICQ和QQ就是使用的UDP協議。