您好,登錄后才能下訂單哦!
這篇文章主要講解了“Python網(wǎng)絡(luò)編程UDP協(xié)議分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Python網(wǎng)絡(luò)編程UDP協(xié)議分析”吧!
UDP協(xié)議——User Datagram Protocol,即用戶數(shù)據(jù)包協(xié)議,UDP協(xié)議是無連接、不可靠、高效率數(shù)據(jù)傳輸協(xié)議。
UDP協(xié)議優(yōu)點:開銷小、速度快、無連接。
UDP協(xié)議缺點:無確認(rèn)重傳和排序、無流控制、無錯誤恢復(fù)。
UDP協(xié)議是面向報文的傳輸協(xié)議,它對報文既不拆分也不合并,而是給報文添加頭部后就向下交給IP層。發(fā)現(xiàn)錯誤時不要重傳,只是簡單地把錯誤的報文扔掉、或給應(yīng)用程序提供警告。
UDP協(xié)議廣泛運用在強調(diào)數(shù)據(jù)傳輸速率的多媒體應(yīng)用領(lǐng)域,例如網(wǎng)絡(luò)聊天、在線視頻、網(wǎng)絡(luò)游戲、實時監(jiān)控、路由協(xié)議中修改路由表等。
TCP協(xié)議遇到丟包或錯誤時要求重傳,因而導(dǎo)致傳輸速率大幅降低。
UDP協(xié)議遇到丟包或錯誤時不要求重傳,因為一個報文丟失后幾秒內(nèi)會有新的報文替代它,所以UDP協(xié)議傳輸速率比TCP協(xié)議高很多。
應(yīng)用程序需要根據(jù)需要自定義應(yīng)用層協(xié)議來處理報文丟失、錯誤、失序的情況。
編寫UDP應(yīng)用程序需要審慎考慮合適的報文長度:
局域網(wǎng)最大傳輸單元(Maximum Transmission Unit,MTU)默認(rèn)是1500字節(jié)。
UDP協(xié)議頭部是8字節(jié)、IP層協(xié)議頭部是20字節(jié)。
單條報文建議長度是1024字節(jié),最大長度不得超過65507字節(jié)(報文加頭部總長不得超過65535字節(jié))。
網(wǎng)絡(luò)環(huán)境較好時報文長度及接收緩存建議設(shè)大一些,可以減少報文接收不及時導(dǎo)致丟包的概率。
創(chuàng)建socket實例。
sk = socket.socket(type=socket.SOCK_DGRAM)
注意:type=socket.SOCK_DGRAM是指定關(guān)鍵字參數(shù),不能“缺省type=”,該參數(shù)用來指定使用udp協(xié)議。
綁定ip和端口。
sk.bind(('127.0.0.1',9001))
說明:該方法有一個參數(shù),類型是元組(元組的第一個元素是IP,第二個元素是端口)。無返回值。
從UDP客戶端收報文。
message,addrress = sk.recvfrom(1024)
說明:該方法參數(shù)是接收消息長度。返回值是元組,元組第一項是消息,第二項是ip及端口。
發(fā)送報文給UDP客戶端。
sk.sendto(message,address)
說明:該方法有二個參數(shù),第一個參數(shù)是要發(fā)送的消息,必須是bytes型;第二個參數(shù)是元組(元組的第一個元素是IP,第二個元素是端口)。返回值是發(fā)送的字節(jié)數(shù)。
創(chuàng)建socket實例。
sk = socket.socket()
發(fā)報文給UDP服務(wù)端。
sk.sendto(message.encode(),('127.0.0.1',9001))
說明:該方法有二個參數(shù),第一個參數(shù)是要發(fā)送的消息,必須是bytes型;第二個參數(shù)是元組(元組的第一個元素是IP,第二個元素是端口)。返回值是發(fā)送的字節(jié)數(shù)。
從UDP服務(wù)端收報文。
message = sk.recv(1024).decode()
說明:該方法參數(shù)是接收消息長度。返回值是消息。
服務(wù)端
import socket HOST = '127.0.0.1' # IP地址PORT = 50007 # 端口max_connect = 5def main():accounts = { }with socket.socket(type=socket.SOCK_DGRAM) as sk:sk.bind((HOST, PORT))while True:msg, address = sk.recvfrom(1024)rev = msg.decode().split('|||')accounts[rev[0]] = addressif rev[1] in accounts:sk.sendto(msg, accounts[rev[1]])if __name__ == "__main__":main()
說明:這個是UDP協(xié)議簡易聊天室服務(wù)端模型,服務(wù)端接收到客戶端發(fā)來的消息,會記錄客戶端的ip和端口以及賬號,并更新到字典中。遇到發(fā)往目標(biāo)賬戶的消息在字典中時,會將信息轉(zhuǎn)發(fā)給目標(biāo)賬戶,從而實現(xiàn)多人聊天功能。
注意:代碼目前沒有緩存消息,當(dāng)要發(fā)送的目標(biāo)不在線時,該消息會被丟棄。
客戶端
import socketfrom threading import Threadimport sys HOST = '127.0.0.1' # IP地址PORT = 50007 # 端口class Transceiver:def __init__(self, conn, server, account: str, target: str, buffer: int = 1024) -> None:self.conn = conn # socket實例self.server = server # 目標(biāo)ip及端口self.buffer = buffer # 緩存區(qū)大小self.path = (account + '|||' + target + '|||').encode() # 己方賬號def send(self, message: str) -> None:"""發(fā)送消息"""if type(message) is str: # 判斷消息類型message = message.encode() # 將消息轉(zhuǎn)成bytes型,缺省參數(shù)是utf8編碼self.conn.sendto(self.path + message, self.server) # 發(fā)送消息def recv(self):"""接收消息"""message, _ = self.conn.recvfrom(self.buffer)message = message.decode('utf8').split('|||')return message[1], message[2] # 返回消息字符串def main():def send(m, message):m.send(message)def recv(m):while True:try:source, data = m.recv()print(f'收到"{source}"發(fā)來的信息:{data}')except:passwith socket.socket(type=socket.SOCK_DGRAM) as sk:account = input("請輸入你的賬號:")target = input("請輸入你想聊天的賬號:")m = Transceiver(sk, (HOST, PORT), account, target)t = Thread(target=recv, args=(m,))t.setDaemon(True)t.start()while True:message = input('請輸入你要發(fā)送的信息:')if not message:continueif message == 'q' or message == 'Q':sys.exit(0)Thread(target=send, args=(m, message)).start()if __name__ == "__main__":main()
說明:這個是udp協(xié)議簡易聊天室客戶端模型,客戶端登錄時首先輸入自己的賬號和對方的賬號,然后進入循環(huán),循環(huán)輸入發(fā)給對方賬號的消息,另開了子收獲進程接受服務(wù)端轉(zhuǎn)發(fā)來的消息。
感謝各位的閱讀,以上就是“Python網(wǎng)絡(luò)編程UDP協(xié)議分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Python網(wǎng)絡(luò)編程UDP協(xié)議分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。