溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

python UDP編程的案例分析

發(fā)布時(shí)間:2020-08-25 09:58:37 來源:億速云 閱讀:179 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹python UDP編程的案例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

前面我們講了 TCP 編程,我們知道 TCP 可以建立可靠連接,并且通信雙方都可以以流的形式發(fā)送數(shù)據(jù)。本文我們再來介紹另一個(gè)常用的協(xié)議–UDP。相對(duì)TCP,UDP則是面向無連接的協(xié)議。

UDP 協(xié)議

我們來看 UDP 的定義:

UDP 協(xié)議(User Datagram Protocol),中文名是用戶數(shù)據(jù)報(bào)協(xié)議,是 OSI(Open System Interconnection,開放式系統(tǒng)互聯(lián)) 參考模型中一種無連接的傳輸層協(xié)議,提供面向事務(wù)的簡單不可靠信息傳送服務(wù)。

從這個(gè)定義中,我們可以總結(jié)出 UDP 的幾個(gè)特點(diǎn)以及其與 TCP 的區(qū)別:

  • UDP 是用戶數(shù)據(jù)報(bào)協(xié)議,傳輸模式是數(shù)據(jù)報(bào),而 TCP 是基于字節(jié)流的傳輸協(xié)議。
  • UDP 是無連接的協(xié)議,每個(gè)數(shù)據(jù)報(bào)都是一個(gè)獨(dú)立的信息,包括完整的源地址或目的地址,它在網(wǎng)絡(luò)上以任何可能的路徑傳往目的地,因此能否到達(dá)目的地,到達(dá)目的地的時(shí)間以及內(nèi)容的正確性都是不能被保證的。
  • UDP 是簡單不可靠的協(xié)議,它不提供可靠性,只是把數(shù)據(jù)包發(fā)送出去,并不保證能夠到達(dá)目的地。由于它不需要在客戶端和服務(wù)端之間建立連接,也沒有超時(shí)重發(fā)機(jī)制,所以傳輸速度很快。
     

從以上特點(diǎn),我們可以看到 UDP 適合應(yīng)用在每次傳輸數(shù)據(jù)量小、對(duì)數(shù)據(jù)完整性要求不高、對(duì)傳輸速度要求高的領(lǐng)域。這里面最典型的就是即時(shí)通信的場景,微信是一個(gè)很常見的例子。相信大家在使用微信的時(shí)候都遇到過先發(fā)的消息后收到,或者有些發(fā)送的消息對(duì)方?jīng)]有收到的情況吧,這就是 UDP 協(xié)議典型的特點(diǎn),不保證傳輸數(shù)據(jù)的完整性和順序性。除此之外, UDP 還應(yīng)用在在線視頻、網(wǎng)絡(luò)電話等場景。

UDP 傳輸過程

我們在講 TCP 的時(shí)候,我們說 TCP 客戶端和服務(wù)端必須先連接才可以傳輸數(shù)據(jù):客戶端先請(qǐng)求連接服務(wù)器,服務(wù)器接受連接請(qǐng)求,然后雙方才可以通信。在 UDP 協(xié)議里,客戶端只需要知道服務(wù)器的地址和端口號(hào),就可以直接發(fā)送數(shù)據(jù)了。

我們來看下 UDP 傳輸?shù)牧鞒虉D:

python UDP編程的案例分析

UDP服務(wù)器的建立可以歸納這幾步:

  • 創(chuàng)建 socket(套接字)
  • 綁定 socket 的 IP 地址和端口號(hào)
  • 接收客戶端數(shù)據(jù)
  • 關(guān)閉連接

udp客戶端的創(chuàng)建可總結(jié)為這幾步:

  • 創(chuàng)建 socket(套接字)
  • 向服務(wù)器發(fā)送數(shù)據(jù)
  • 關(guān)閉連接
     

這里需要注意的是 UDP 客戶端連接到服務(wù)器的 IP 和端口號(hào)必須是 UDP 服務(wù)器的 IP 和監(jiān)聽的端口號(hào),服務(wù)器服務(wù)器只需要綁定 IP 和端口號(hào),就可以時(shí)刻準(zhǔn)備接收客戶端發(fā)送的數(shù)據(jù),此時(shí)服務(wù)器處于阻塞狀態(tài),直到接收到數(shù)據(jù)為止。

UDP 客戶端

創(chuàng)建 socket,可以這樣做:

# 導(dǎo)入socket庫
import socket

# 創(chuàng)建一個(gè)socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

創(chuàng)建 socket 時(shí),第一個(gè)參數(shù) socket.AF_INET 表示指定使用 IPv4 協(xié)議,如果要使用 IPv6 協(xié)議,就指定為 socket.AF_INET6。SOCK_DGRAM 指定基于 UDP 的數(shù)據(jù)報(bào)式 Socket 通信。

創(chuàng)建了 socket 之后,我們就可以向目標(biāo)地址發(fā)送數(shù)據(jù)報(bào)了:

# 發(fā)送數(shù)據(jù)
s.sendto(b'Hello Server', ('127.0.0.1', 6000))

第一個(gè)參數(shù)是需要發(fā)送的數(shù)據(jù)報(bào)內(nèi)容,第二個(gè)參數(shù)是 IP 地址和端口號(hào)的二元組。

如果是接收數(shù)據(jù)的話,我們可以這樣寫:

# 接收數(shù)據(jù)
data, addr = s.recv(1024)
# 解碼接收到的數(shù)據(jù)
data = data.decode('utf-8')

接收信息的時(shí)候,第一個(gè) data 表示接收到的數(shù)據(jù), addr 是對(duì)方的 IP 地址和端口號(hào)的二元組。

想要關(guān)閉 socket,直接調(diào)用 close() 方法即可:

# 關(guān)閉 socket
socket.close()

UDP 服務(wù)器

相比于客戶端,服務(wù)器端只是多了一個(gè)步驟,在創(chuàng)建 socket 之后,需要綁定一個(gè) IP 地址和端口號(hào),以便接收客戶端隨時(shí)可能發(fā)送過來的數(shù)據(jù)。綁定的方法為:

# 綁定 IP 和端口
s.bind(('127.0.0.1', 6000))

UDP 簡單實(shí)例

我們通過一個(gè)簡單的實(shí)例來體會(huì)下 UDP 的客戶端和服務(wù)器的通信流程。

服務(wù)器代碼為:

import socket

# 創(chuàng)建 socket
sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定 IP 和端口號(hào)
sk.bind(('127.0.0.1', 6000))
while True:
  # 接收數(shù)據(jù)報(bào)
  msg, addr = sk.recvfrom(1024)
  # 打印
  print('來自[%s:%s]的消息: %s' % (addr[0], addr[1], msg.decode('utf-8')))

  # 等待輸入
  inp = input('>>>')
  # 發(fā)送數(shù)據(jù)報(bào)
  sk.sendto(inp.encode('utf-8'), addr)

# 關(guān)閉 socket
sk.close()

這里,我們先創(chuàng)建 socket,然后綁定本機(jī)的6000端口,然后等待接收客戶端發(fā)送的數(shù)據(jù)報(bào),接收到數(shù)據(jù)后將數(shù)據(jù)內(nèi)容打印在控制臺(tái)。然后可以在控制臺(tái)輸入回復(fù)內(nèi)容,發(fā)送給客戶端。

客戶端代碼:

import socket

# 創(chuàng)建 socket
sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ('127.0.0.1', 6000)
while True:
  # 等待輸入
  msg = input('>>>')
  # 發(fā)送數(shù)據(jù)報(bào)
  sk.sendto(msg.encode('utf-8'), addr)
  # 接收數(shù)據(jù)報(bào)
  msg_recv, addr = sk.recvfrom(1024)
  # 打印
  print(msg_recv.decode('utf-8'))

# 關(guān)閉 socket
sk.close()

在客戶端代碼中,我們就只是創(chuàng)建 socket,然后在控制臺(tái)輸入需要向服務(wù)器發(fā)送的內(nèi)容,通過 sentto() 方法發(fā)送給服務(wù)器,然后接收服務(wù)器返回的內(nèi)容,將接收的內(nèi)容打印到控制臺(tái)。

分別運(yùn)行客戶端和服務(wù)器代碼,然后我們在客戶端的控制臺(tái)輸入 “hello server”,我們可以看到服務(wù)器的控制臺(tái)打印了客戶端發(fā)送的內(nèi)容,然后我們在服務(wù)器控制臺(tái)輸入 “hello client”,同樣在客戶端控制臺(tái)可以看你到內(nèi)容。

下面是客戶端的控制臺(tái)內(nèi)容:

>>>hello server
hello client
>>>

下面是服務(wù)器的控制臺(tái)內(nèi)容:

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

這個(gè)實(shí)例其實(shí)就是一個(gè)簡單的聊天模型,客戶端和服務(wù)器就像兩個(gè)人一樣可以發(fā)送和接收對(duì)方的信息。

那么多人群聊怎么實(shí)現(xiàn)呢?簡單來說,我們需要設(shè)置一臺(tái)中心服務(wù)器,我們每個(gè)人發(fā)送的內(nèi)容都先發(fā)送到中心服務(wù)器,然后中心服務(wù)器再轉(zhuǎn)發(fā)到每個(gè)群聊的人。

以上是python UDP編程的案例分析的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI