溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Node.js API詳解之 如何使用dgram模塊

發(fā)布時(shí)間:2020-07-18 11:37:15 來(lái)源:億速云 閱讀:825 作者:小豬 欄目:web開(kāi)發(fā)

小編這次要給大家分享的是Node.js API詳解之 如何使用dgram模塊,文章內(nèi)容豐富,感興趣的小伙伴可以來(lái)了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

本文實(shí)例講述了Node.js API詳解之 dgram模塊用法。分享給大家供大家參考,具體如下:

Node.js API詳解之 dgram

dgram模塊提供了 UDP 數(shù)據(jù)包 socket 的實(shí)現(xiàn)。

使用以下方式引用:

const dgram = require('dgram');

dgram.createSocket(options[, callback])

說(shuō)明:

創(chuàng)建一個(gè) dgram.Socket 對(duì)象. 一旦創(chuàng)建了套接字,調(diào)用 socket.bind() 會(huì)指示套接字開(kāi)始監(jiān)聽(tīng)數(shù)據(jù)報(bào)消息。
如果 address 和 port 沒(méi)傳給 socket.bind(),
那么這個(gè)方法會(huì)把這個(gè)套接字綁定到 “全部接口” 地址的一個(gè)隨機(jī)端口(這適用于 udp4 和 udp6 套接字)。
綁定的地址和端口可以通過(guò) socket.address().address 和socket.address().port 來(lái)獲取
options:
type:套接字族. 必須是 ‘udp4' 或 ‘udp6'. 必需填.
reuseAddr:若設(shè)置為 true socket.bind() ,則會(huì) 重用地址,即時(shí)另一個(gè)進(jìn)程已經(jīng)在其上面綁定了一個(gè)套接字。 默認(rèn)是 false.
recvBufferSize: 設(shè)置 SO_RCVBUF 套接字值。
sendBufferSize: 設(shè)置 SO_SNDBUF 套接字值。
lookup:慣常的查詢函數(shù). 默認(rèn)是 dns.lookup()。
callback:為 ‘message' 事件綁定一個(gè)監(jiān)聽(tīng)器??蛇x。

demo:

const dgram = require('dgram');
const server = dgram.createSocket({type: 'udp4'}, () => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234);
// 服務(wù)器監(jiān)聽(tīng) 0.0.0.0:41234

dgram.createSocket(type[, callback])

說(shuō)明:

創(chuàng)建一個(gè)特定 type 的dgram.Socket 對(duì)象。type參數(shù)是udp4 或 udp6。
可選傳一個(gè)回調(diào)函數(shù),作為 ‘message' 事件的監(jiān)聽(tīng)器。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234);

dgram.Socket 類(lèi)

說(shuō)明:

dgram.Socket對(duì)象是一個(gè)封裝了數(shù)據(jù)包函數(shù)功能的EventEmitter。
dgram.Socket實(shí)例是由dgram.createSocket()創(chuàng)建的。
創(chuàng)建dgram.Socket實(shí)例不需要使用new關(guān)鍵字。

socket.bind([port][, address][, callback])

說(shuō)明:

對(duì)于 UDP socket,該方法會(huì)令dgram.Socket在指定的port和可選的address上監(jiān)聽(tīng)數(shù)據(jù)包信息。
若port未指定或?yàn)?0,操作系統(tǒng)會(huì)嘗試綁定一個(gè)隨機(jī)的端口。
若address未指定,操作系統(tǒng)會(huì)嘗試在所有地址上監(jiān)聽(tīng)。
綁定完成時(shí)會(huì)觸發(fā)一個(gè)'listening'事件,并會(huì)調(diào)用callback方法。
注意,同時(shí)監(jiān)聽(tīng)'listening'事件和在socket.bind()方法中傳入callback參數(shù)并不會(huì)帶來(lái)壞處,但也不是很有用。
一個(gè)被綁定的數(shù)據(jù)包 socket 會(huì)令 Node.js 進(jìn)程保持運(yùn)行以接收數(shù)據(jù)包信息。
若綁定失敗,一個(gè)'error'事件會(huì)被觸發(fā)。在極少數(shù)的情況下(例如嘗試綁定一個(gè)已關(guān)閉的 socket),一個(gè) Error 會(huì)被拋出。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234, () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});
// 服務(wù)器監(jiān)聽(tīng) 0.0.0.0:41234

socket.bind(options[, callback])

說(shuō)明:

options:{port:”, address: ”, exclusive: ”}
對(duì)于 UDP socket,該方法會(huì)令dgram.Socket在指定的port和可選的address上監(jiān)聽(tīng)數(shù)據(jù)包信息。
若port未指定或?yàn)?0,操作系統(tǒng)會(huì)嘗試綁定一個(gè)隨機(jī)的端口。
若address未指定,操作系統(tǒng)會(huì)嘗試在所有地址上監(jiān)聽(tīng)。
綁定完成時(shí)會(huì)觸發(fā)一個(gè)'listening'事件,并會(huì)調(diào)用callback方法。
在配合cluster模塊使用dgram.Socket對(duì)象時(shí),options對(duì)象可能包含一個(gè)附加的exclusive屬性。
當(dāng)exclusive被設(shè)為false(默認(rèn)值)時(shí),集群工作單元會(huì)使用相同的 socket 句柄來(lái)共享連接處理作業(yè)。
當(dāng)exclusive被設(shè)為true時(shí),該句柄將不會(huì)被共享,而嘗試共享端口則會(huì)造成錯(cuò)誤。
一個(gè)綁定的數(shù)據(jù)報(bào) socket 會(huì)使 Node.js 進(jìn)程持續(xù)運(yùn)行以接受數(shù)據(jù)報(bào)消息。
如果綁定失敗,一個(gè) ‘error' 事件會(huì)產(chǎn)生。在極少數(shù)情況下(例如嘗試綁定一個(gè)已經(jīng)關(guān)閉的 socket), 一個(gè) Error 可能拋出。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.bind({port: 41234}, () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});
// 服務(wù)器監(jiān)聽(tīng) 0.0.0.0:41234

listening 事件

說(shuō)明:

當(dāng)一個(gè) socket 開(kāi)始監(jiān)聽(tīng)數(shù)據(jù)包信息時(shí),'listening'事件將被觸發(fā)。
該事件會(huì)在創(chuàng)建 UDP socket 之后被立即觸發(fā)。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});
server.bind({port: 41234});
// 服務(wù)器監(jiān)聽(tīng) 0.0.0.0:41234

error 事件

說(shuō)明:

當(dāng)有任何錯(cuò)誤發(fā)生時(shí),'error'事件將被觸發(fā)。
事件發(fā)生時(shí),事件處理函數(shù)僅會(huì)接收到一個(gè) Error 參數(shù)。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
 console.log(`服務(wù)器異常:\n${err.stack}`);
 server.close();
});
server.on('message', (msg, rinfo) => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});
server.bind({port: 41234});

message 事件

說(shuō)明:

當(dāng)有新的數(shù)據(jù)包被 socket 接收時(shí),'message'事件會(huì)被觸發(fā)。
msg和rinfo會(huì)作為參數(shù)傳遞到該事件的處理函數(shù)中。
msg:消息
rinfo:遠(yuǎn)程地址信息
address:發(fā)送方地址
family: 地址類(lèi)型 (‘IPv4' or ‘IPv6')
port: 發(fā)送者端口
size: 消息大小

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
 console.log(`服務(wù)器收到:${msg} 來(lái)自 ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});
server.bind({port: 41234});

socket.getRecvBufferSize()

說(shuō)明:

socket 接收到的字節(jié)大小。

demo:

server.on('message', (msg, rinfo) => {
 console.log(`服務(wù)器收到字節(jié)數(shù):${socket.getRecvBufferSize()}`);
});

socket.setRecvBufferSize(size)

說(shuō)明:

設(shè)置 SO_RCVBUF 套接字選項(xiàng)。設(shè)置最大的套接字接收緩沖字節(jié)。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.setRecvBufferSize(1024);
server.on('message', (msg, rinfo) => {
 console.log(`服務(wù)器收到字節(jié)數(shù):${socket.getRecvBufferSize()}`);
});
server.bind({port: 41234});

socket.send(msg, [offset, length,] port [, address] [, callback])

說(shuō)明:

在 socket 上發(fā)送一個(gè)數(shù)據(jù)包。目標(biāo)port和address須被指定。
msg參數(shù)包含了要發(fā)送的消息。根據(jù)消息的類(lèi)型可以有不同的做法。
如果msg是一個(gè)Buffer 或 Uint8Array,則offset和length指定了消息在Buffer中對(duì)應(yīng)的偏移量和字節(jié)數(shù)。
如果msg是一個(gè)String,那么它會(huì)被自動(dòng)地按照utf8編碼轉(zhuǎn)換為Buffer。
對(duì)于包含了多字節(jié)字符的消息,offset和length會(huì)根據(jù)對(duì)應(yīng)的byte length進(jìn)行計(jì)算,而不是根據(jù)字符的位置。
如果msg是一個(gè)數(shù)組,那么offset和length必須都不能被指定。
address參數(shù)是一個(gè)字符串。若address的值是一個(gè)主機(jī)名,則 DNS 會(huì)被用來(lái)解析主機(jī)的地址。
若address未提供或是非真值,則'127.0.0.1'(用于 udp4 socket)或'::1'(用于 udp6 socket)會(huì)被使用。
若在之前 socket 未通過(guò)調(diào)用bind方法進(jìn)行綁定,socket 將會(huì)被一個(gè)隨機(jī)的端口號(hào)賦值并綁定到“所有接口”的地址上(對(duì)于udp4 socket 是'0.0.0.0',對(duì)于udp6 socket 是'::0')。
可以指定一個(gè)可選的callback方法來(lái)匯報(bào) DNS 錯(cuò)誤或判斷可以安全地重用buf對(duì)象的時(shí)機(jī)。
注意,在 Node.js 事件循環(huán)中,DNS 查詢會(huì)對(duì)發(fā)送造成至少 1 tick 的延遲。
確定數(shù)據(jù)包被發(fā)送的唯一方式就是指定callback。若在callback被指定的情況下有錯(cuò)誤發(fā)生,該錯(cuò)誤會(huì)作為callback的第一個(gè)參數(shù)。
若callback未被指定,該錯(cuò)誤會(huì)以'error'事件的方式投射到socket對(duì)象上。
偏移量和長(zhǎng)度是可選的,但如其中一個(gè)被指定則另一個(gè)也必須被指定。
另外,他們只在第一個(gè)參數(shù)是Buffer 或 Uint8Array 的情況下才能被使用。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
server.on('error', (err) => {
 console.log(`服務(wù)器異常:\n${err.stack}`);
 server.close();
});
server.on('message', (msg, rinfo) => {
 console.log(`服務(wù)器收到字節(jié)數(shù):${socket.getRecvBufferSize()}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});
server.send([buf1, buf2], 8080, 'localhost');
server.bind({port: 41234});

socket.getSendBufferSize()

說(shuō)明:

socket 發(fā)送的字節(jié)大小。

demo:

server.send([buf1, buf2], 8080, 'localhost', () => {
 console.log('發(fā)送消息字節(jié)數(shù):', server.getSendBufferSize());
});

socket.setSendBufferSize(size)

說(shuō)明:

設(shè)置 SO_SNDBUF 套接字選項(xiàng)。設(shè)置最大的套接字發(fā)送緩沖字節(jié)。

demo:

const socket = dgram.createSocket('udp6');
socket.bind(1234, () => {
 socket.setSendBufferSize(1024);
});

socket.unref()

說(shuō)明:

默認(rèn)情況下,綁定一個(gè) socket 會(huì)在 socket 運(yùn)行時(shí)阻止 Node.js 進(jìn)程退出。
socket.unref() 方法用于將 socket 從維持 Node.js 進(jìn)程的引用列表中解除。
可以使用 socket.ref() 再次激活。
socket.unref() 方法返回一個(gè)對(duì) socket 的引用,所以可以鏈?zhǔn)秸{(diào)用。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234, () => {
 socket.unref();
});

socket.ref()

說(shuō)明:

默認(rèn)情況下,綁定一個(gè) socket 會(huì)在 socket 運(yùn)行時(shí)阻止 Node.js 進(jìn)程退出。
socket.unref() 方法用于將 socket 從維持 Node.js 進(jìn)程的引用列表中解除。
socket.ref() 方法用于將 socket 重新添加到這個(gè)引用列表中,并恢復(fù)其默認(rèn)行為。
多次調(diào)用 socket.ref() 不會(huì)有額外的作用。
socket.ref() 方法返回一個(gè)對(duì) socket 的引用,所以可以鏈?zhǔn)秸{(diào)用。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234, () => {
 socket.unref();
 socket.ref()
});

socket.close([callback])

說(shuō)明:

關(guān)閉該 socket 并停止監(jiān)聽(tīng)其上的數(shù)據(jù)。
如果提供了一個(gè)回調(diào)函數(shù),它就相當(dāng)于為'close'事件添加了一個(gè)監(jiān)聽(tīng)器。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234);
socket.close(() => {
 console.log('socket 已關(guān)閉');
});
// socket 已關(guān)閉

close 事件

說(shuō)明:

‘close'事件將在使用close()關(guān)閉一個(gè) socket 之后觸發(fā)。
該事件一旦觸發(fā),這個(gè) socket 上將不會(huì)觸發(fā)新的'message'事件。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234);
socket.on('close', () => {
 console.log('socket 已關(guān)閉');
})
socket.close();
// socket 已關(guān)閉

socket.address()

說(shuō)明:

返回一個(gè)包含 socket 地址信息的對(duì)象。
對(duì)于 UDP socket,該對(duì)象將包含address、family和port屬性。

demo:

server.on('listening', () => {
 const address = server.address();
 console.log(`服務(wù)器監(jiān)聽(tīng) ${address.address}:${address.port}`);
});

socket.addMembership(multicastAddress[, multicastInterface])

說(shuō)明:

通知內(nèi)核將multicastAddress和multicastInterface提供的多路傳送集合通過(guò)IP_ADD_MEMBERSHIP這個(gè) socket 選項(xiàng)結(jié)合起來(lái)。
若multicastInterface參數(shù)未指定,操作系統(tǒng)將會(huì)選擇一個(gè)接口并向其添加成員。
要為所有可用的接口添加成員,可以在每個(gè)接口上調(diào)用一次addMembership方法。

socket.dropMembership(multicastAddress[, multicastInterface])

說(shuō)明:

引導(dǎo)內(nèi)核通過(guò)IP_DROP_MEMBERSHIP這個(gè) socket 選項(xiàng)刪除multicastAddress指定的多路傳送集合。
當(dāng) socket 被關(guān)閉或進(jìn)程被終止時(shí),該方法會(huì)被內(nèi)核自動(dòng)調(diào)用,所以大多數(shù)的應(yīng)用都不用自行調(diào)用該方法。
若multicastInterface未指定,操作系統(tǒng)會(huì)嘗試刪除所有可用接口上的成員。

socket.setBroadcast(flag)

說(shuō)明:

設(shè)置或清除 SO_BROADCAST socket 選項(xiàng)。
當(dāng)設(shè)置為 true, UDP包可能會(huì)被發(fā)送到一個(gè)本地接口的廣播地址

socket.setMulticastLoopback(flag)

說(shuō)明:

設(shè)置或清除 IP_MULTICAST_LOOP socket 選項(xiàng)。當(dāng)設(shè)置為 true, 多播數(shù)據(jù)包也將在本地接口接收。

socket.setMulticastTTL(ttl)

說(shuō)明:

設(shè)置IP_MULTICAST_TTL套接字選項(xiàng)。 一般來(lái)說(shuō),TTL表示”生存時(shí)間”。這里特指一個(gè)IP數(shù)據(jù)包傳輸時(shí)允許的最大跳步數(shù),尤其是對(duì)多播傳輸。
當(dāng)IP數(shù)據(jù)包每向前經(jīng)過(guò)一個(gè)路由或網(wǎng)關(guān)時(shí),TTL值減1,若經(jīng)過(guò)某個(gè)路由時(shí),TTL值被減至0,便不再繼續(xù)向前傳輸。
傳給 socket.setMulticastTTL() 的參數(shù)是一個(gè)范圍為0-255的跳步數(shù)。大多數(shù)系統(tǒng)的默認(rèn)值是 1 ,但是可以變化。

socket.setTTL(ttl)

說(shuō)明:

設(shè)置 IP_TTL 套接字選項(xiàng)。 一般來(lái)說(shuō),TTL表示”生存時(shí)間”,這里特指一個(gè)IP數(shù)據(jù)包傳輸時(shí)允許的最大跳步數(shù)。
當(dāng)IP數(shù)據(jù)包每向前經(jīng)過(guò)一個(gè)路由或網(wǎng)關(guān)時(shí),TTL值減1,若經(jīng)過(guò)某個(gè)路由時(shí),TTL值被減至0,便不再繼續(xù)向前傳輸。
比較有代表性的是,為了進(jìn)行網(wǎng)絡(luò)情況嗅探或者多播而修改TTL值。
傳給 socket.setTTL() 的參數(shù)是一個(gè)范圍為0-255的跳步數(shù)。大多數(shù)系統(tǒng)的默認(rèn)值是 1 ,但是可以變化。

看完這篇關(guān)于Node.js API詳解之 如何使用dgram模塊的文章,如果覺(jué)得文章內(nèi)容寫(xiě)得不錯(cuò)的話,可以把它分享出去給更多人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI