UDP簡介
- User Datagram Protocol, 簡稱UDP,又稱為用戶數據報協議。
- 和TCP一樣,位於網路傳輸層,用於處理數據包。
- UDP最大的特點是無連接
- UDP傳輸速度快
- UDP數據傳輸不可靠
- 不提供數據包分組,組裝和不能對數據包進行排序的缺點,也就是說,當報文發送之后,是無法得知其是否安全完整到達的。
- 可靠性由應用層負責
- 支持一對一通信,也支持一對多通信
- 許多關鍵的互聯網應用程序使用UDP
- 如DNS域名系統服務,TFTP簡單文件傳輸協議、DHCP動態主機設置協議等
- UDP適用於對速度要求比較高、對數據質量要求不嚴謹的應用
- 例如流媒體、實時多人游戲、實時音視頻
UDP的三種傳播方式
- UDP單播
- 單播是目的地址為單一目標的一種傳播方式
- 地址范圍: 0.0.0.0 ~ 223.255.255.255
- UDP廣播
- 受限廣播: 它不被路由轉發,IP地址的網絡字段為1就是地址 255.255.255.255
- 直接廣播: 會被路由轉發,IP地址的網絡字段定義這個網絡,主機字段通常全為1,如192.168.10.255
- UDP組播
- 組播就是把信息傳遞給一組目的地址
- 地址范圍:224.0.0.0~239.255.255.255
- 224.0.0.0~224.0.0.255 為永久組地址,244.0.0.0 保留不分配,其他供路由協議使用。
- 224.0.1.0~224.0.1.255 為公用組播地址,可以用於internet。
- 224.0.2.0~238.255.255.255 為用戶可用的組播地址(臨時組),全網范圍有效,使用需要申請。
- 239.0.0.0~ 239.255.255.255 為本地管理組播,僅在特定本地范圍有效。
Node中的dgram模塊
Node為我們提供了 dgram模塊用於構建UDP服務
使用該模塊創建UDP套接字非常簡單,UDP套接字一旦創建,即可以作為客戶端發送數據,也可以作為服務器接受數據。
UDP單播示例:
const dgram = require('dgram')
const server = dgram.createSocket('udp4')
// 當綁定端口好啟動成功后觸發
server.on('listening', () => {
const address = server.address()
console.log(`client running ${address.address}: ${address.port}`)
})
// 當收到消息時觸發
server.on('message', (msg, remoteInfo) => {
console.log(`來自客戶端消息:【${msg}】 from ${remoteInfo.address}: ${remoteInfo.port}`)
server.send('word', remoteInfo.port, remoteInfo.address)
})
// 發生異常觸發
server.on('error', err => {
console.log('server error', err)
})
// 綁定端口號
server.bind(20000)
const dgram = require('dgram')
const client = dgram.createSocket('udp4')
// 當綁定端口好啟動成功后觸發
client.on('listening', () => {
const address = client.address()
console.log(`client running ${address.address}: ${address.port}`)
})
// 發送消息
client.send('hello', 20000, 'localhost')
// 當收到消息時觸發
client.on('message', (msg, remoteInfo) => {
console.log(`來自服務端消息:【${msg}】 from ${remoteInfo.address}:${remoteInfo.port}`)
})
// 發生異常觸發
client.on('error', err => {
console.log('client error', err)
})
// 綁定端口號
// client.bind(20001)
UDP 廣播示例:
發送消息:
const dgram = require('dgram')
const server = dgram.createSocket('udp4')
// 當綁定端口好啟動成功后觸發
server.on('listening', () => {
const info = server.address()
console.log(`server running ${info.address}: ${info.port}`)
// 開啟廣播模式
server.setBroadcast(true)
// 案例: 每隔兩秒發送一條消息
let a = 1
setInterval(() => {
// 直接地址 可以經過路由轉發
// 受限地址 255.255.255.255 不會經過路由轉發,只在當前連接的路由器局域網中
server.send(`測試數據${a++}`, 20001, '255.255.255.255')
}, 2000)
})
// 綁定端口號
server.bind(20000)
接收消息:
const dgram = require('dgram')
const client = dgram.createSocket('udp4')
// 當收到消息時觸發
client.on('message', (msg, remoteInfo) => {
console.log(`收到消息:【${msg}】 from ${remoteInfo.address}:${remoteInfo.port}`)
})
// 綁定端口號
client.bind(20001)
UDP組播示例
發送數據:
// 組播
const dgram = require('dgram')
const server = dgram.createSocket('udp4')
// 當綁定端口好啟動成功后觸發
server.on('listening', () => {
const info = server.address()
console.log(`server running ${info.address}: ${info.port}`)
// 案例: 每隔兩秒向組播發送一條消息
let a = 1
setInterval(() => {
server.send(`測試數據${a++}`, 20001, '224.1.1.101')
}, 2000)
})
// 綁定端口號
server.bind(20000)
接收數據:
// 組播
const dgram = require('dgram')
const client = dgram.createSocket('udp4')
client.on('listening', () => {
// 加入組播的組
client.addMembership('224.1.1.101')
})
// 當收到消息時觸發
client.on('message', (msg, remoteInfo) => {
console.log(`收到消息:【${msg}】 from ${remoteInfo.address}:${remoteInfo.port}`)
})
// 綁定端口號
client.bind(20001)