1. 程式人生 > 程式設計 >詳解python UDP 程式設計

詳解python UDP 程式設計

前面我們講了 TCP 程式設計,我們知道 TCP 可以建立可靠連線,並且通訊雙方都可以以流的形式傳送資料。本文我們再來介紹另一個常用的協議–UDP。相對TCP,UDP則是面向無連線的協議。

UDP 協議

我們來看 UDP 的定義:

UDP 協議(User Datagram Protocol),中文名是使用者資料報協議,是 OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無連線的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務。

從這個定義中,我們可以總結出 UDP 的幾個特點以及其與 TCP 的區別:

  • UDP 是使用者資料報協議,傳輸模式是資料報,而 TCP 是基於位元組流的傳輸協議。
  • UDP 是無連線的協議,每個資料報都是一個獨立的資訊,包括完整的源地址或目的地址,它在網路上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。
  • UDP 是簡單不可靠的協議,它不提供可靠性,只是把資料包傳送出去,並不保證能夠到達目的地。由於它不需要在客戶端和服務端之間建立連線,也沒有超時重發機制,所以傳輸速度很快。

從以上特點,我們可以看到 UDP 適合應用在每次傳輸資料量小、對資料完整性要求不高、對傳輸速度要求高的領域。這裡面最典型的就是即時通訊的場景,微信是一個很常見的例子。相信大家在使用微信的時候都遇到過先發的訊息後收到,或者有些傳送的訊息對方沒有收到的情況吧,這就是 UDP 協議典型的特點,不保證傳輸資料的完整性和順序性。除此之外, UDP 還應用在線上視訊、網路電話等場景。

UDP 傳輸過程

我們在講 TCP 的時候,我們說 TCP 客戶端和服務端必須先連線才可以傳輸資料:客戶端先請求連線伺服器,伺服器接受連線請求,然後雙方才可以通訊。在 UDP 協議裡,客戶端只需要知道伺服器的地址和埠號,就可以直接傳送資料了。

我們來看下 UDP 傳輸的流程圖:

詳解python UDP 程式設計

UDP伺服器的建立可以歸納這幾步:

  • 建立 socket(套接字)
  • 繫結 socket 的 IP 地址和埠號
  • 接收客戶端資料
  • 關閉連線

udp客戶端的建立可總結為這幾步:

  • 建立 socket(套接字)
  • 向伺服器傳送資料
  • 關閉連線

這裡需要注意的是 UDP 客戶端連線到伺服器的 IP 和埠號必須是 UDP 伺服器的 IP 和監聽的埠號,伺服器伺服器只需要繫結 IP 和埠號,就可以時刻準備接收客戶端傳送的資料,此時伺服器處於阻塞狀態,直到接收到資料為止。

UDP 客戶端

建立 socket,可以這樣做:

# 匯入socket庫
import socket

# 建立一個socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

建立 socket 時,第一個引數 socket.AF_INET 表示指定使用 IPv4 協議,如果要使用 IPv6 協議,就指定為 socket.AF_INET6。SOCK_DGRAM 指定基於 UDP 的資料報式 Socket 通訊。

建立了 socket 之後,我們就可以向目標地址傳送資料報了:

# 傳送資料
s.sendto(b'Hello Server',('127.0.0.1',6000))

第一個引數是需要傳送的資料報內容,第二個引數是 IP 地址和埠號的二元組。

如果是接收資料的話,我們可以這樣寫:

# 接收資料
data,addr = s.recv(1024)
# 解碼接收到的資料
data = data.decode('utf-8')

接收資訊的時候,第一個 data 表示接收到的資料, addr 是對方的 IP 地址和埠號的二元組。

想要關閉 socket,直接呼叫 close() 方法即可:

# 關閉 socket
socket.close()

UDP 伺服器

相比於客戶端,伺服器端只是多了一個步驟,在建立 socket 之後,需要繫結一個 IP 地址和埠號,以便接收客戶端隨時可能傳送過來的資料。繫結的方法為:

# 繫結 IP 和埠
s.bind(('127.0.0.1',6000))

UDP 簡單例項

我們通過一個簡單的例項來體會下 UDP 的客戶端和伺服器的通訊流程。

伺服器程式碼為:

import socket

# 建立 socket
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 繫結 IP 和埠號
sk.bind(('127.0.0.1',6000))
while True:
  # 接收資料報
  msg,addr = sk.recvfrom(1024)
  # 列印
  print('來自[%s:%s]的訊息: %s' % (addr[0],addr[1],msg.decode('utf-8')))

  # 等待輸入
  inp = input('>>>')
  # 傳送資料報
  sk.sendto(inp.encode('utf-8'),addr)

# 關閉 socket
sk.close()

這裡,我們先建立 socket,然後繫結本機的6000埠,然後等待接收客戶端傳送的資料報,接收到資料後將資料內容列印在控制檯。然後可以在控制檯輸入回覆內容,傳送給客戶端。

客戶端程式碼:

import socket

# 建立 socket
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
addr = ('127.0.0.1',6000)
while True:
  # 等待輸入
  msg = input('>>>')
  # 傳送資料報
  sk.sendto(msg.encode('utf-8'),addr)
  # 接收資料報
  msg_recv,addr = sk.recvfrom(1024)
  # 列印
  print(msg_recv.decode('utf-8'))

# 關閉 socket
sk.close()

在客戶端程式碼中,我們就只是建立 socket,然後在控制檯輸入需要向伺服器傳送的內容,通過 sentto() 方法傳送給伺服器,然後接收伺服器返回的內容,將接收的內容列印到控制檯。

分別執行客戶端和伺服器程式碼,然後我們在客戶端的控制檯輸入 “hello server”,我們可以看到伺服器的控制檯列印了客戶端傳送的內容,然後我們在伺服器控制檯輸入 “hello client”,同樣在客戶端控制檯可以看你到內容。

下面是客戶端的控制檯內容:

>>>hello server
hello client
>>>

下面是伺服器的控制檯內容:

來自[127.0.0.1:61207]的訊息: hello server
>>>hello client

這個例項其實就是一個簡單的聊天模型,客戶端和伺服器就像兩個人一樣可以傳送和接收對方的資訊。

那麼多人群聊怎麼實現呢?簡單來說,我們需要設定一臺中心伺服器,我們每個人傳送的內容都先發送到中心伺服器,然後中心伺服器再轉發到每個群聊的人。

總結

本文為大家介紹了 UDP 程式設計的基本原理以及通過 Python 實現一個最簡單的聊天程式來模擬 UDP 通訊的過程。通過本文的學習,我們需要對 UDP 協議有基本的認識,以及對 UDP 的通訊過程比較熟悉。

以上就是詳解python UDP 程式設計的詳細內容,更多關於python UDP 程式設計的資料請關注我們其它相關文章!