摘要:組播向一個(gè)組播地址發(fā)送數(shù)據(jù)報(bào),該組網(wǎng)絡(luò)下的所有主機(jī)都會(huì)受到影響,主機(jī)根據(jù)端口號(hào)來(lái)判斷是否丟棄該數(shù)據(jù)。向組播地址發(fā)送數(shù)據(jù)報(bào),只有該組成員才會(huì)接收此數(shù)據(jù)報(bào)。模塊的方法將加入組播組中,方法退出組播組。模塊實(shí)現(xiàn)通信同步更新
1、什么是UDP?
這里簡(jiǎn)單介紹下,UDP,即用戶數(shù)據(jù)報(bào)協(xié)議,一種面向無(wú)連接的傳輸層協(xié)議,提供不可靠的消息傳送服務(wù)。UDP協(xié)議使用端口號(hào)為不同的應(yīng)用保留其各自的數(shù)據(jù)傳輸通道,這一點(diǎn)非常重要。與TCP相比,占用資源更少,傳輸速度更快。
2、了解UDP單播、廣播和組播單播:向一個(gè)單播地址發(fā)送UDP數(shù)據(jù)報(bào)時(shí),數(shù)據(jù)報(bào)只能被指定的IP主機(jī)接收,同一子網(wǎng)下的其它主機(jī)都不會(huì)接收該數(shù)據(jù)報(bào)。單播過(guò)程(假設(shè)子網(wǎng)地址:192.168.10,該子網(wǎng)下有兩臺(tái)主機(jī):192.168.10.2,192.168.10.3,向192.168.10.2發(fā)送數(shù)據(jù)報(bào))
向主機(jī)192.168.10.2的8060端口發(fā)送數(shù)據(jù)報(bào),該IP數(shù)據(jù)報(bào)目標(biāo)IP在以太網(wǎng)中被ARP解析成MAC地址,然后將此MAC地址設(shè)置為目標(biāo)地址發(fā)出去。
該子網(wǎng)下的主機(jī)以太網(wǎng)接口看到該數(shù)據(jù)幀時(shí),對(duì)比自己的MAC地址,如果不一樣,則忽略該數(shù)據(jù)幀。
直到192.168.10.2主機(jī)看到該數(shù)據(jù)幀時(shí),發(fā)現(xiàn)MAC一致,則讀入該數(shù)據(jù)幀,然后在IP層對(duì)比目標(biāo)IP和本機(jī)IP,在UDP層對(duì)比端口號(hào)是否一致,最后接收該數(shù)據(jù)幀。
廣播:向一個(gè)廣播地址發(fā)送UDP數(shù)據(jù)報(bào),該廣播網(wǎng)絡(luò)下的所有主機(jī)都會(huì)受到影響,主機(jī)根據(jù)端口號(hào)來(lái)判斷是否丟棄該數(shù)據(jù)。廣播過(guò)程(假設(shè)子網(wǎng)地址:192.168.10,則該網(wǎng)絡(luò)的廣播地址為:192.168.10.255,該子網(wǎng)下有兩臺(tái)主機(jī):192.168.10.2,192.168.10.3,向192.168.10.255發(fā)送數(shù)據(jù)報(bào)):
向192.168.10.255主機(jī)端口為8060發(fā)送數(shù)據(jù)報(bào),,該IP數(shù)據(jù)報(bào)目標(biāo)IP在以太網(wǎng)中被ARP解析成MAC地址,然后將此MAC地址設(shè)置為目標(biāo)地址發(fā)出去。
192.168.10.2和192.168.10.3的主機(jī)接口都會(huì)和此廣播地址匹配成功,直到該數(shù)據(jù)報(bào)進(jìn)入傳輸層時(shí)根據(jù)端口是否匹配判斷是否丟棄該數(shù)據(jù),端口為8060的會(huì)保留該數(shù)據(jù),否則將數(shù)據(jù)丟棄。
組播:向一個(gè)組播地址發(fā)送UDP數(shù)據(jù)報(bào),該組網(wǎng)絡(luò)下的所有主機(jī)都會(huì)受到影響,主機(jī)根據(jù)端口號(hào)來(lái)判斷是否丟棄該數(shù)據(jù)。組播過(guò)程原理與廣播類似。
3.dgram 模塊API介紹該模塊用來(lái)創(chuàng)建UDP數(shù)據(jù)報(bào)socket,繼承了EventEmitter,該模塊的API如下所示:
3.1 UDP單播實(shí)現(xiàn)服務(wù)端:
const dgram = require("dgram"), server = dgram.createSocket("udp4"); server.on("close", () => { console.log("socket已經(jīng)關(guān)閉"); }) server.on("error", (err) => { console.log(err); }) server.on("listening", () => { console.log("socket正在監(jiān)聽..."); }) 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)
客戶端:
const dgram = require("dgram"), client = dgram.createSocket("udp4"); client.on("close", () => { console.log("socket已經(jīng)關(guān)閉"); }) client.on("error", (err) => { console.log(err); }) client.on("listening", () => { console.log("socket正在監(jiān)聽"); }) 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廣播實(shí)現(xiàn)
要實(shí)現(xiàn)UDP廣播,就必須知道廣播地址,廣播地址如何計(jì)算呢?可以利用ipconfig(windows)或ifconfig(*unix)得到ip地址和mask掩碼地址,然后利用ip地址與mask子網(wǎng)掩碼做與操作得到網(wǎng)絡(luò)地址,網(wǎng)絡(luò)地址中主機(jī)位都為1就是廣播地址,舉個(gè)例子:
IP:149.88.160.58 mask:11111111.11111111.11000000.00000000
IP&MASK得到網(wǎng)絡(luò)地址:149.88.128.0/18 網(wǎng)絡(luò)號(hào)就是主機(jī)位全為0,即149.88.10000000.00000000
即149.88.128.0 廣播地址就是主機(jī)位全為1,即149.88.10111111.11111111即149.88.191.255
接著實(shí)現(xiàn)UDP廣播,我機(jī)子的IP為192.168.0.193,掩碼為255.255.255.0,因此廣播地址為192.168.0.255,服務(wù)端向廣播地址的8061端口發(fā)送數(shù)據(jù)報(bào),客戶端綁定本機(jī)的8061端口,如下所示:
服務(wù)端:
const dgram = require("dgram"), server = dgram.createSocket("udp4"); server.on("close", () => { console.log("socket已關(guān)閉...."); }); server.on("listening", () => { console.log("socket正在監(jiān)聽..."); server.setBroadcast(true); server.setTTL(128); setInterval(() => { server.send("大家好啊,我是服務(wù)端.", 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已關(guān)閉..."); }) client.on("error",err=>{ console.log(err); }) client.on("listening",()=>{ console.log("正在監(jiān)聽..."); }) client.on("message",(msg,rinfo)=>{ console.log(`msg from server:${msg}`); }) client.bind(8061,"192.168.0.193")3.3 UDP組播實(shí)現(xiàn)
組播地址是實(shí)現(xiàn)UDP組播的關(guān)鍵,因此了解組播地址是重點(diǎn)。什么是組播地址?IANA將D類地址
(224.0.0.0-239.255.255.255)分配給IP組播,用來(lái)標(biāo)識(shí)一個(gè)IP組播組,由IGMP(組管理協(xié)議)協(xié)議維護(hù)組成員關(guān)系,其中:
224.0.0.0~224.0.0.255為永久組地址,地址224.0.0.0保留不做分配,其它地址供路由協(xié)議使用;
224.0.1.0~224.0.1.255是公用組播地址,可以用于Internet;
224.0.2.0~238.255.255.255為用戶可用的組播地址(臨時(shí)組地址),全網(wǎng)范圍內(nèi)有效;
239.0.0.0~239.255.255.255為本地管理組播地址,僅在特定的本地范圍內(nèi)有效。 向組播地址發(fā)送數(shù)據(jù)報(bào),只有該組成員才會(huì)接收此數(shù)據(jù)報(bào)。
dgram模塊的addMembership()方法將socket加入組播組中,dropMembership()方法退出組播組。下面以組播地址224.100.100.100來(lái)實(shí)現(xiàn)UDP組播,如下所示:
服務(wù)端:
const dgram = require("dgram"), server = dgram.createSocket("udp4"), multicastAddr = "224.100.100.100"; server.on("error",err=>{ console.log("socket已關(guān)閉"); }) server.on("error",(err)=>{ console.log(err); }); server.on("listening",()=>{ console.log("socket正在監(jiān)聽中....."); 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("大家好啊,我是服務(wù)端.",8061,multicastAddr); } server.bind(8060);
客戶端:
const dgram = require("dgram"), client = dgram.createSocket("udp4"), multicastAddr = "224.100.100.100"; client.on("close", () => { console.log("socket已關(guān)閉..."); }) client.on("error", err => { console.log(err); }) client.on("listening", () => { console.log("socket正在監(jiān)聽..."); client.addMembership(multicastAddr); }) client.on("message", (msg, rinfo) => { console.log(`msg from server:${msg}`); }) client.bind(8061)
另外UDP內(nèi)網(wǎng)穿透相關(guān)的內(nèi)容,大家也可自行了解一下。
CSDN【Node dgram模塊實(shí)現(xiàn)UDP通信】同步更新
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/88705.html
摘要:在任何類型的通信開始之前,網(wǎng)絡(luò)應(yīng)用程序必須創(chuàng)建套接字。基于文件的套接字,家族名又名基于網(wǎng)絡(luò)的套接字,家族名在和后續(xù)的版本中,支持的套接字有,,,。中的網(wǎng)絡(luò)編程在中主要是用模塊來(lái)實(shí)現(xiàn)基于套接字的網(wǎng)絡(luò)通信。 python學(xué)習(xí)記錄--網(wǎng)絡(luò)編程 1、套接字介紹 一臺(tái)機(jī)器上的不同進(jìn)程之間進(jìn)行通信可以利用隊(duì)列,管道等,但是不同機(jī)器之間的進(jìn)程進(jìn)行通信用隊(duì)列是不行的,解決這個(gè)問(wèn)題就是網(wǎng)絡(luò)套接字。 套接...
摘要:進(jìn)程間通信的目的是為了讓不同的進(jìn)程能夠互相訪問(wèn)資源,并進(jìn)程協(xié)調(diào)工作。這個(gè)過(guò)程的示意圖如下端口共同監(jiān)聽集群穩(wěn)定之路進(jìn)程事件自動(dòng)重啟負(fù)載均衡狀態(tài)共享模塊工作原理事件二測(cè)試單元測(cè)試性能測(cè)試三產(chǎn)品化項(xiàng)目工程化部署流程性能日志監(jiān)控報(bào)警穩(wěn)定性異構(gòu)共存 內(nèi)容 9.玩轉(zhuǎn)進(jìn)程10.測(cè)試11.產(chǎn)品化 一、玩轉(zhuǎn)進(jìn)程 node的單線程只不過(guò)是js層面的單線程,是基于V8引擎的單線程,因?yàn)椋琕8的緣故,前后...
摘要:是建立可靠連接,并且通信雙方都可以以流的形式發(fā)送數(shù)據(jù)。相對(duì),則是面向無(wú)連接的協(xié)議。測(cè)試結(jié)果用兩個(gè)命令行分別啟動(dòng)服務(wù)器和客戶端測(cè)試開啟服務(wù)端完成一次通信 UDP TCP是建立可靠連接, 并且通信雙方都可以以流的形式發(fā)送數(shù)據(jù)。 相對(duì)TCP, UDP則是面向無(wú)連接的協(xié)議。使用UDP協(xié)議時(shí), 不需要建立連接, 只需要知道對(duì)方的IP地址和端口號(hào), 就可以直接發(fā)數(shù)據(jù)包。 但是, 能不能到達(dá)就不知道...
摘要:子進(jìn)程使用反序列化消息字符串為消息對(duì)象。在調(diào)用這類方法時(shí),遍歷列表中的實(shí)例發(fā)送內(nèi)部消息,子進(jìn)程列表中的對(duì)應(yīng)項(xiàng)收到內(nèi)部消息并處理返回,父進(jìn)程中再結(jié)合返回結(jié)果和對(duì)應(yīng)著這個(gè)類實(shí)例維護(hù)的信息,保證功能的正確性。 在 Node.js 中,當(dāng)我們使用 child_process 模塊創(chuàng)建子進(jìn)程后,會(huì)返回一個(gè) ChildProcess 類的實(shí)例,通過(guò)調(diào)用 ChildProcess#send(mess...
摘要:創(chuàng)建創(chuàng)建通信接受套接字的數(shù)據(jù),與類似,但返回值是。發(fā)送數(shù)據(jù),將數(shù)據(jù)發(fā)送到,形式為,指定遠(yuǎn)程地址發(fā)送,返回值是發(fā)送的字節(jié)數(shù)發(fā)送的報(bào)文是類型,發(fā)送的報(bào)文是類型,在發(fā)送前要記得編碼。 UDP 和 TCP 的區(qū)別 ? TCP UDP 連接性 面向連接 面向無(wú)連接 傳輸可靠性 可靠 不可靠 傳輸模式 流 數(shù)據(jù)報(bào) 應(yīng)用場(chǎng)景 傳輸大量的數(shù)據(jù) 少量數(shù)據(jù) 速度 慢 快 T...
閱讀 3120·2021-11-10 11:36
閱讀 3320·2021-10-13 09:40
閱讀 6127·2021-09-26 09:46
閱讀 669·2019-08-30 15:55
閱讀 1416·2019-08-30 15:53
閱讀 1586·2019-08-29 13:55
閱讀 3004·2019-08-29 12:46
閱讀 3218·2019-08-29 12:34