UDP-用戶數(shù)據(jù)報協(xié)議

1.介紹

UDP --- 用戶數(shù)據(jù)報協(xié)議后控,是一個無連接的簡單的面向數(shù)據(jù)報的運輸層協(xié)議御雕。UDP不提供可靠性垛玻,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報發(fā)送出去冤留,但是并不能保證它們能到達目的地。由于UDP在傳輸數(shù)據(jù)報前不用在客戶和服務(wù)器之間建立一個連接倡鲸,且沒有超時重發(fā)等機制供嚎,故而傳輸速度很快。

UDP是一種面向無連接的協(xié)議,每個數(shù)據(jù)報都是一個獨立的信息克滴,包括完整的源地址或目的地址逼争,它在網(wǎng)絡(luò)上以任何可能的路徑傳往目的地,因此能否到達目的地劝赔,到達目的地的時間以及內(nèi)容的正確性都是不能被保證的誓焦。

特點:UDP是面向無連接的通訊協(xié)議,UDP數(shù)據(jù)包括目的端口號和源端口號信息着帽,由于通訊不需要連接杂伟,所以可以實現(xiàn)廣播發(fā)送。 UDP傳輸數(shù)據(jù)時有大小限制仍翰,每個被傳輸?shù)臄?shù)據(jù)報必須限定在64KB之內(nèi)赫粥。 UDP是一個不可靠的協(xié)議,發(fā)送方所發(fā)送的數(shù)據(jù)報并不一定以相同的次序到達接收方予借。
UDP是面向消息的協(xié)議越平,通信時不需要建立連接,數(shù)據(jù)的傳輸自然是不可靠的灵迫,UDP一般用于多點通信和實時的數(shù)據(jù)業(yè)務(wù)秦叛,比如

  • 語音廣播
  • 視頻
  • QQ
  • TFTP(簡單文件傳送)
  • SNMP(簡單網(wǎng)絡(luò)管理協(xié)議)
  • RIP(路由信息協(xié)議,如報告股票市場龟再,航空信息)
  • DNS(域名解釋)

查看端口

  • 用“netstat -an”查看端口狀態(tài)

2.udp網(wǎng)絡(luò)程序-發(fā)送數(shù)據(jù)

socket函數(shù)
mySocket = socket(family, type)
函數(shù)socket()的參數(shù)family用于設(shè)置網(wǎng)絡(luò)通信的域书闸,函數(shù)socket()根據(jù)這個參數(shù)選擇通信協(xié)議的族尼变。通信協(xié)議族在文件sys/socket.h中定義利凑。

通信協(xié)議族

函數(shù)socket()的參數(shù)type用于設(shè)置套接字通信的類型,主要有SOCKET_STREAM(流式套接字)嫌术、SOCK——DGRAM(數(shù)據(jù)包套接字)等哀澈。
并不是所有的協(xié)議族都實現(xiàn)了這些協(xié)議類型,例如度气,AF_INET協(xié)議族就沒有實現(xiàn)SOCK_SEQPACKET協(xié)議類型割按。

udp網(wǎng)絡(luò)程序-發(fā)送、接收數(shù)據(jù)

from socket import *

#1. 創(chuàng)建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

#2. 準備接收方的地址
sendAddr = ('192.168.1.103', 8080)

#3. 從鍵盤獲取數(shù)據(jù)
sendData = input("請輸入要發(fā)送的數(shù)據(jù):")

#4. 發(fā)送數(shù)據(jù)到指定的電腦上
udpSocket.sendto(sendData, sendAddr)

#5. 等待接收對方發(fā)送的數(shù)據(jù)
recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字節(jié)數(shù)

#6. 顯示對方發(fā)送的數(shù)據(jù)
print(recvData)

#7. 關(guān)閉套接字
udpSocket.close()

echo服務(wù)器

from socket import *

# 1. 創(chuàng)建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

# 2. 綁定本地的相關(guān)信息
bindAddr = ('', 7788)  # ip地址和端口號磷籍,ip一般不用寫适荣,表示本機的任何一個ip
udpSocket.bind(bindAddr)

num = 1
while True:
    # 3. 等待接收對方發(fā)送的數(shù)據(jù)
    recvData = udpSocket.recvfrom(1024)  # 1024表示本次接收的最大字節(jié)數(shù)

    # 4. 將接收到的數(shù)據(jù)再發(fā)送給對方
    #udpSocket.sendto(recvData[0], recvData[1])
    udpSocket.sendto(str(len(recvData[0].decode('gbk'))).encode('gbk'), recvData[1])

    # 5. 統(tǒng)計信息
    print('已經(jīng)將接收到的第%d個數(shù)據(jù)返回給對方,內(nèi)容為:%s' % (num, recvData[0].decode('gbk')))
    num += 1

# 5. 關(guān)閉套接字
udpSocket.close()

廣播

import socket
'''
1、一對一  點對點          單播
2院领、一對多                  多播
3弛矛、一對所有                廣播
'''
#創(chuàng)建socket對象
udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#開啟廣播
udpSocket.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
#目的地:如果是''表示當(dāng)前IP,如果是'<broadcast>'表示當(dāng)前所在的廣播地址
destAdress = ('<broadcast>',2425)
#消息內(nèi)容
sendMsg = input('>>')
#編碼
sendMsg = sendMsg.encode('gbk')
#發(fā)送
udpSocket.sendto(sendMsg,destAdress)

while True:
    (content,address) = udpSocket.recvfrom(1024)
    print("received from %s----%s" % (address, content.decode('gbk')))

#關(guān)閉socket對象
udpSocket.close()
print('over......')

要查看當(dāng)前廣播位置有3種方法

用代碼給飛秋發(fā)信息

'''
    應(yīng)用程序可以在通用的tcp/ip協(xié)議基礎(chǔ)上比然,加上自己的判斷丈氓,組成新的應(yīng)用層協(xié)議。
    比如飛秋,使用的是udp協(xié)議万俗,在此基礎(chǔ)上包裝成了IPMSG協(xié)議湾笛。
    格式:
    版本號:包編號:發(fā)送者姓名:發(fā)送者機器名:命令字:消息
    1:12323434:user:machine:32:hello
    1::13212321:易烊千璽:【易烊千璽】:32:努力來見我


    注:現(xiàn)行的IPMSG協(xié)議的版本是1
'''
import socket

udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

destAdress = ('192.168.11.66',2425)

sendMsg = input('>.')

sendMsg = sendMsg.encode('gbk')
udpSocket.sendto(sendMsg,destAdress)

udpSocket.close()
print('over..')

運行結(jié)果:

>.1::13212321:易烊千璽:【易烊千璽】:32:努力來見我
over..

收消息_沒綁定端口號

import socket

udpSocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
destAdress=('192.168.11.66',8888)

sendMsg = input('--')

sendMsg = sendMsg.encode('gb2312')

udpSocket.sendto(sendMsg,destAdress)

recvMsg=udpSocket.recvfrom(1024)
recvMsg='【Receive from %s : %s 】: %s'%(recvMsg[1][0],recvMsg[1][1],recvMsg[0].decode('gbk'))
print(recvMsg)

udpSocket.close()
print('over.......')

收消息_綁定端口

import socket

#創(chuàng)建socket對象
udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
'''
綁定,
第一個參數(shù)是本地ip,不指定也可以闰歪,默認會幫你填充,建議不寫
第二個參數(shù)是端口號嚎研,不要與本地的端口號沖突
'''
localAdress = ('',8081)
udpSocket.bind(localAdress)
#目的地
destAdress = ('192.168.11.66',8888)
#消息內(nèi)容
#sendMsg = input('>>')
#編碼
#sendMsg = sendMsg.encode('gb2312')
#發(fā)送
#udpSocket.sendto(sendMsg,destAdress)

'''
收,這個緩沖區(qū)不是越大越好,如果發(fā)送方的數(shù)據(jù)库倘,大于緩沖區(qū)嘉赎,丟包,報錯于樟。
如果收不到公条,阻塞
'''
recvMsg = udpSocket.recvfrom(1024)
recvMsg = '【Receive from %s : %s】:%s'%(recvMsg[1][0],recvMsg[1][1],recvMsg[0].decode('gbk'))
print(recvMsg)

#關(guān)閉socket對象
udpSocket.close()
print('over......')

多線程聊天

'''
收和發(fā)互相不影響:
    這是兩個獨立的功能,可以考慮兩個線程
'''
from socket import *
from threading import *
import  os

'''全局變量'''
# socket
udpSocket = None
# ip
destIp = None
# port
destPort = None


# 收
def recv():
    while True:
        recvInfo = udpSocket.recvfrom(1024)
        print("\r<<%s:%s%s>>" % (str(recvInfo[1]), recvInfo[0].decode('gbk'),os.linesep),end='')


# 發(fā)
def send():
    while True:
        info = input('>>')
        udpSocket.sendto(info.encode('gbk'), (destIp, destPort))


# 主方法
def main():
    global udpSocket
    global destIp
    global destPort

    udpSocket = socket(AF_INET, SOCK_DGRAM)
    bindAddr = ('', 8888)  # ip地址和端口號迂曲,ip一般不用寫靶橱,表示本機的任何一個ip
    udpSocket.bind(bindAddr)

    #destIp = input("對方的ip:")
    #destPort = int(input("對方的port:"))
    destIp = '192.168.11.66'
    destPort = 8080

    tSend = Thread(target=send)
    tRecv = Thread(target=recv)

    tSend.start()
    tRecv.start()


if __name__ == '__main__':
    main()

結(jié)果:

>>北方有佳人
<<('192.168.11.66', 8080):遺世而獨立
>>一顧傾人城
<<('192.168.11.66', 8080):再顧傾人國
>>

注釋

  • os.linesep字符串給出當(dāng)前平臺使用的行終止符。例如路捧,Windows使用'\r\n'关霸,Linux使用'\n'而Mac使用'\r'。
  • \r 默認表示將輸出的內(nèi)容返回到第一個指針杰扫,這樣的話队寇,后面的內(nèi)容會覆蓋前面的內(nèi)容
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市章姓,隨后出現(xiàn)的幾起案子佳遣,更是在濱河造成了極大的恐慌,老刑警劉巖凡伊,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件零渐,死亡現(xiàn)場離奇詭異,居然都是意外死亡系忙,警方通過查閱死者的電腦和手機诵盼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來银还,“玉大人风宁,你說我怎么就攤上這事∮挤瑁” “怎么了戒财?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苍苞。 經(jīng)常有香客問我固翰,道長狼纬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任骂际,我火速辦了婚禮疗琉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歉铝。我一直安慰自己盈简,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布太示。 她就那樣靜靜地躺著柠贤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪类缤。 梳的紋絲不亂的頭發(fā)上臼勉,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音餐弱,去河邊找鬼宴霸。 笑死,一個胖子當(dāng)著我的面吹牛膏蚓,可吹牛的內(nèi)容都是我干的瓢谢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼驮瞧,長吁一口氣:“原來是場噩夢啊……” “哼氓扛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起论笔,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤采郎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后翅楼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尉剩,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡真慢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年毅臊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黑界。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡管嬉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朗鸠,到底是詐尸還是另有隱情蚯撩,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布烛占,位于F島的核電站胎挎,受9級特大地震影響沟启,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜犹菇,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一德迹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揭芍,春花似錦胳搞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姑原,卻和暖如春悬而,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锭汛。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工摊滔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人店乐。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓艰躺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親眨八。 傳聞我的和親對象是個殘疾皇子腺兴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容