【Node dgram模塊實現UDP通訊】

一、什麼是UDP?

這裏簡單介紹下,UDP,即用戶數據報協議,一種面向無鏈接的傳輸層協議,提供不可靠的消息傳送服務。UDP協議使用端口號爲不一樣的應用保留其各自的數據傳輸通道,這一點很是重要。與TCP相比,佔用資源更少,傳輸速度更快。windows

二、瞭解UDP單播、廣播和組播

單播:向一個單播地址發送UDP數據報時,數據報只能被指定的IP主機接收,同一子網下的其它主機都不會接收該數據報。單播過程(假設子網地址:192.168.10,該子網下有兩臺主機:192.168.10.2,192.168.10.3,向192.168.10.2發送數據報)網絡

  1. 向主機192.168.10.2的8060端口發送數據報,該IP數據報目標IP在以太網中被ARP解析成MAC地址,而後將此MAC地址設置爲目標地址發出去。
  2. 該子網下的主機以太網接口看到該數據幀時,對比本身的MAC地址,若是不同,則忽略該數據幀。
  3. 直到192.168.10.2主機看到該數據幀時,發現MAC一致,則讀入該數據幀,而後在IP層對比目標IP和本機IP,在UDP層對比端口號是否一致,最後接收該數據幀。

廣播:向一個廣播地址發送UDP數據報,該廣播網絡下的全部主機都會受到影響,主機根據端口號來判斷是否丟棄該數據。廣播過程(假設子網地址:192.168.10,則該網絡的廣播地址爲:192.168.10.255,該子網下有兩臺主機:192.168.10.2,192.168.10.3,向192.168.10.255發送數據報):socket

  1. 向192.168.10.255主機端口爲8060發送數據報,,該IP數據報目標IP在以太網中被ARP解析成MAC地址,而後將此MAC地址設置爲目標地址發出去。
  2. 192.168.10.2和192.168.10.3的主機接口都會和此廣播地址匹配成功,直到該數據報進入傳輸層時根據端口是否匹配判斷是否丟棄該數據,端口爲8060的會保留該數據,不然將數據丟棄。

組播:向一個組播地址發送UDP數據報,該組網絡下的全部主機都會受到影響,主機根據端口號來判斷是否丟棄該數據。組播過程原理與廣播相似。ui

3.dgram 模塊API介紹

該模塊用來建立UDP數據報socket,繼承了EventEmitter,該模塊的API以下所示:spa

圖片描述

3.1 UDP單播實現

服務端:.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');

3.2 UDP廣播實現

要實現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")

3.3 UDP組播實現

組播地址是實現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通訊】同步更新

相關文章
相關標籤/搜索