這裏簡單介紹下,UDP,即用戶數據報協議,一種面向無鏈接的傳輸層協議,提供不可靠的消息傳送服務。UDP協議使用端口號爲不一樣的應用保留其各自的數據傳輸通道,這一點很是重要。與TCP相比,佔用資源更少,傳輸速度更快。windows
單播:向一個單播地址發送UDP數據報時,數據報只能被指定的IP主機接收,同一子網下的其它主機都不會接收該數據報。單播過程(假設子網地址:192.168.10,該子網下有兩臺主機:192.168.10.2,192.168.10.3,向192.168.10.2發送數據報)網絡
廣播:向一個廣播地址發送UDP數據報,該廣播網絡下的全部主機都會受到影響,主機根據端口號來判斷是否丟棄該數據。廣播過程(假設子網地址:192.168.10,則該網絡的廣播地址爲:192.168.10.255,該子網下有兩臺主機:192.168.10.2,192.168.10.3,向192.168.10.255發送數據報):socket
組播:向一個組播地址發送UDP數據報,該組網絡下的全部主機都會受到影響,主機根據端口號來判斷是否丟棄該數據。組播過程原理與廣播相似。ui
該模塊用來建立UDP數據報socket,繼承了EventEmitter,該模塊的API以下所示:spa
服務端:.net
const dgram = require("dgram"), server = dgram.createSocket("udp4"); server.on("close", () => { console.log("socket已經關閉"); }) server.on("error", (err) => { console.log(err); }) server.on("listening", () => { console.log("socket正在監聽..."); }) server.on("message", (msg, rinfo) => { console.log(`message from client ${rinfo.address}:${rinfo.port}-${msg}`); server.send(`welcome ${rinfo.address}:${rinfo.port}`, rinfo.port, rinfo.address); setTimeout(function () { server.send(`exit`, rinfo.port, rinfo.address); }, 2000); }) server.bind(8060)
客戶端:3d
const dgram = require("dgram"), client = dgram.createSocket("udp4"); client.on("close", () => { console.log("socket已經關閉"); }) client.on("error", (err) => { console.log(err); }) client.on("listening", () => { console.log("socket正在監聽"); }) client.on("message", (msg, rinfo) => { if (msg == "exit") { client.close(); } console.log(`message from server ${rinfo.address}:${rinfo.port}-${msg}`); }) client.send(`hello`,8060,'127.0.0.1');
要實現UDP廣播,就必須知道廣播地址,廣播地址如何計算呢?能夠利用ipconfig(windows)或ifconfig(*unix)獲得ip地址和mask掩碼地址,而後利用ip地址與mask子網掩碼作與操做獲得網絡地址,網絡地址中主機位都爲1就是廣播地址,舉個例子:unix
IP:149.88.160.58 mask:11111111.11111111.11000000.00000000
IP&MASK獲得網絡地址:149.88.128.0/18 網絡號就是主機位全爲0,即149.88.10000000.00000000
即149.88.128.0 廣播地址就是主機位全爲1,即149.88.10111111.11111111即149.88.191.255code
接着實現UDP廣播,我機子的IP爲192.168.0.193,掩碼爲255.255.255.0,所以廣播地址爲192.168.0.255,服務端向廣播地址的8061端口發送數據報,客戶端綁定本機的8061端口,以下所示:server
服務端:
const dgram = require("dgram"), server = dgram.createSocket("udp4"); server.on("close", () => { console.log("socket已關閉...."); }); server.on("listening", () => { console.log("socket正在監聽..."); server.setBroadcast(true); server.setTTL(128); setInterval(() => { server.send("你們好啊,我是服務端.", 8061, "192.168.0.255") }, 2000) }) server.on("message", (msg, rinfo) => { console.log(`msg from client ${rinfo.address}:${rinfo.port}`); }) server.bind(8060,"192.168.0.193");
客戶端:
const dgram = require("dgram"), client = dgram.createSocket("udp4"); client.on("close",()=>{ console.log("socket已關閉..."); }) client.on("error",err=>{ console.log(err); }) client.on("listening",()=>{ console.log("正在監聽..."); }) client.on("message",(msg,rinfo)=>{ console.log(`msg from server:${msg}`); }) client.bind(8061,"192.168.0.193")
組播地址是實現UDP組播的關鍵,所以瞭解組播地址是重點。什麼是組播地址?IANA將D類地址
(224.0.0.0-239.255.255.255)分配給IP組播,用來標識一個IP組播組,由IGMP(組管理協議)協議維護組成員關係,其中:
224.0.0.0~224.0.0.255爲永久組地址,地址224.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爲本地管理組播地址,僅在特定的本地範圍內有效。 向組播地址發送數據報,只有該組成員纔會接收此數據報。
dgram模塊的addMembership()方法將socket加入組播組中,dropMembership()方法退出組播組。下面以組播地址224.100.100.100來實現UDP組播,以下所示:
服務端:
const dgram = require('dgram'), server = dgram.createSocket("udp4"), multicastAddr = '224.100.100.100'; server.on("error",err=>{ console.log('socket已關閉'); }) server.on('error',(err)=>{ console.log(err); }); server.on("listening",()=>{ console.log("socket正在監聽中....."); server.addMembership(multicastAddr); server.setMulticastTTL(128); setInterval(()=>{ sendMsg(); },1500) }) server.on('message',(msg,rinfo)=>{ console.log(`msg from client ${rinfo.address}:${rinfo.port}`); }); function sendMsg(){ server.send('你們好啊,我是服務端.',8061,multicastAddr); } server.bind(8060);
客戶端:
const dgram = require("dgram"), client = dgram.createSocket("udp4"), multicastAddr = '224.100.100.100'; client.on("close", () => { console.log("socket已關閉..."); }) client.on("error", err => { console.log(err); }) client.on("listening", () => { console.log("socket正在監聽..."); client.addMembership(multicastAddr); }) client.on("message", (msg, rinfo) => { console.log(`msg from server:${msg}`); }) client.bind(8061)
另外UDP內網穿透相關的內容,你們也可自行了解一下。
CSDN【Node dgram模塊實現UDP通訊】同步更新