數(shù)據(jù)報(bào)socket
通過require('dgram')
使用。
重要提示:dgram.Socket#bind()
的表現(xiàn)在v0.10中被改變,并且現(xiàn)在總是異步的,如果你有像這樣的代碼:
var s = dgram.createSocket('udp4');
s.bind(1234);
s.addMembership('224.0.0.114');
你必須改成這樣:
var s = dgram.createSocket('udp4');
s.bind(1234, function() {
s.addMembership('224.0.0.114');
});
'udp4'
或'udp6'
,兩者之一message
事件的監(jiān)聽器socket
對(duì)象創(chuàng)建一個(gè)指定類型的數(shù)據(jù)報(bào)socket
??捎妙愋褪莡dp4和udp6.
接受一個(gè)可選的回調(diào)函數(shù),它會(huì)被自動(dòng)添加為message
事件的監(jiān)聽器。
如果你想要接收數(shù)據(jù)報(bào),調(diào)用socket.bind()
。socket.bind()
將會(huì)到所有網(wǎng)絡(luò)接口
地址中的一個(gè)隨機(jī)端口(不論udp4和upd6 socket
,它都可以正常工作)。你可以從socket.address().address
和socket.address().port
中獲取地址和端口。
message
事件的監(jiān)聽器socket
對(duì)象options
對(duì)象必須包含一個(gè)type
屬性,可是udp4或udp6。還有一個(gè)可選的reuseAddr
布爾值屬性。
當(dāng)reuseAddr
為true
時(shí),socket.bind()
會(huì)重用地址,甚至是當(dāng)另一個(gè)進(jìn)程已經(jīng)在這之上綁定了一個(gè)socket
時(shí)。默認(rèn)為false
。
接受一個(gè)可選的回調(diào)函數(shù),它會(huì)被自動(dòng)添加為message
事件的監(jiān)聽器。
如果你想要接收數(shù)據(jù)報(bào),調(diào)用socket.bind()
。socket.bind()
將會(huì)到所有網(wǎng)絡(luò)接口
地址中的一個(gè)隨機(jī)端口(不論udp4和upd6 socket
,它都可以正常工作)。你可以從socket.address().address
和socket.address().port
中獲取地址和端口。
dgram.Socket
類封裝了數(shù)據(jù)報(bào)的功能。它必須被dgram.createSocket(...)
創(chuàng)建。
當(dāng)在socket
中一個(gè)新的數(shù)據(jù)報(bào)可用時(shí)觸發(fā)。msg
是一個(gè)buffer
并且rinfo
是一個(gè)包含發(fā)送者地址信息的對(duì)象:
socket.on('message', function(msg, rinfo) {
console.log('Received %d bytes from %s:%d\n',
msg.length, rinfo.address, rinfo.port);
});
當(dāng)一個(gè)socket
開始監(jiān)聽數(shù)據(jù)報(bào)時(shí)觸發(fā)。在UDP socket
被創(chuàng)建時(shí)觸發(fā)。
在一個(gè)socket
通過close()
被關(guān)閉時(shí)觸發(fā)。這個(gè)socket
中不會(huì)再觸發(fā)新的message
事件。
當(dāng)錯(cuò)誤發(fā)生時(shí)觸發(fā)。
buffer
里的初始偏移位置。對(duì)于UDP socket
,目標(biāo)端口和地址都必須被指定。address
參數(shù)需要提供一個(gè)字符串,并且它會(huì)被DNS解析。
如果address
被忽略,或者是一個(gè)空字符串。將會(huì)使用'0.0.0.0'
或'::0'
。這取決于網(wǎng)絡(luò)配置,這些默認(rèn)值 可能會(huì) 或 可能不會(huì) 正常工作;所以最好還是明確指定目標(biāo)地址。
如果一個(gè)socket
先前沒有被調(diào)用bind
來綁定,它將會(huì)賦于一個(gè)隨機(jī)端口數(shù)并且被綁定到“所有網(wǎng)絡(luò)接口”地址(udp4 socket
為'0.0.0.0'
,udp6則為'::0'
)。
一個(gè)可選的回調(diào)函數(shù)可以被指定,用來檢測(cè)DNS錯(cuò)誤,或決定重用buf
對(duì)象是否安全。注意,DNS查找至少會(huì)延遲一個(gè)事件循環(huán)。唯一能確定數(shù)據(jù)報(bào)被發(fā)送的方法就是使用一個(gè)回調(diào)函數(shù)。
出于對(duì)多字節(jié)字符的考慮,offset
和length
將會(huì)根據(jù)字節(jié)長度而不是字符位置被計(jì)算。
一個(gè)向localhost
上的一個(gè)隨機(jī)端口發(fā)送UDP報(bào)文的例子:
var dgram = require('dgram');
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost", function(err) {
client.close();
});
IPv4/v6數(shù)據(jù)報(bào)的最大大小取決于MTU
(最大傳輸單位),和Payload Length
字段大小。
Payload Length
是16字節(jié)寬的,意味著一個(gè)正常的負(fù)載不能超過64K 八位字節(jié),包括網(wǎng)絡(luò)頭和數(shù)據(jù)(65,507 字節(jié) = 65,535 ? 8 字節(jié) UDP 頭 ? 20 字節(jié) IP 頭);對(duì)于環(huán)回接口總是true
,但是如此大的數(shù)據(jù)報(bào)對(duì)于大多數(shù)主機(jī)和網(wǎng)絡(luò)來說都是不現(xiàn)實(shí)的。
MTU
是指定的鏈路層技術(shù)支持的報(bào)文的最大大小。對(duì)于所有連接,IPv4允許最小MTU
為68八位字節(jié),而推薦的IPv4 MTU
是576(通常作為撥號(hào)類應(yīng)用的推薦MTU
),無論它們是完整的還是以碎片形式到達(dá)。
對(duì)于IPv6,最小MTU是1280八位字節(jié),但是,允許的最小buffer
重組大小是1500八位字節(jié)。68八位字節(jié)非常小,所以大多數(shù)的當(dāng)前鏈路層技術(shù)的最小MTU
都是1500(如Ethernet
)。
注意,不可能提前知道一個(gè)報(bào)文可能經(jīng)過的每一個(gè)連接MTU
,并且通常不能發(fā)送一個(gè)大于(接收者)MTU
的數(shù)據(jù)報(bào)(報(bào)文會(huì)被默默丟棄,不會(huì)通知源頭:這個(gè)數(shù)據(jù)沒有到達(dá)已定的接收方)。
對(duì)于UDP socket
,監(jiān)聽一個(gè)具名的端口和一個(gè)可選的地址上的數(shù)據(jù)報(bào)。如果address
沒有被指定,操作系統(tǒng)將會(huì)試圖監(jiān)聽所有端口。在綁定完畢后,listening
事件會(huì)被吃法,并且回調(diào)函數(shù)(如果指定了)會(huì)被調(diào)用。同時(shí)指定listening
事件的監(jiān)聽器和callback
沒有危險(xiǎn),但是不是很有用。
一個(gè)綁定的數(shù)據(jù)報(bào)socket
將會(huì)保持io.js
進(jìn)程的運(yùn)行,來接受數(shù)據(jù)報(bào)。
如果綁定失敗,一個(gè)error
事件會(huì)產(chǎn)生。極少數(shù)情況下(例如綁定一個(gè)關(guān)閉的socket
),這個(gè)方法會(huì)拋出一個(gè)錯(cuò)誤。
一個(gè)監(jiān)聽41234端口的UDP服務(wù)器:
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("error", function (err) {
console.log("server error:\n" + err.stack);
server.close();
});
server.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " +
rinfo.address + ":" + rinfo.port);
});
server.on("listening", function () {
var address = server.address();
console.log("server listening " +
address.address + ":" + address.port);
});
server.bind(41234);
// server listening 0.0.0.0:41234
options Object - 必選,支持以下屬性:
exclusive Boolean - 可選
options
的prot
和address
屬性,以及可選的回調(diào)函數(shù),與socket.bind(port, [address], [callback])
中它們的表現(xiàn)一致。
如exclusive
為false
(默認(rèn)),那么集群的工作進(jìn)程將會(huì)使用相同的底層句柄,允許共享處理連接的職責(zé)。當(dāng)為true
時(shí),句柄不被共享,企圖共享端口會(huì)導(dǎo)致一個(gè)錯(cuò)誤。一個(gè)監(jiān)聽一個(gè)exclusive
端口的例子:
socket.bind({
address: 'localhost',
port: 8000,
exclusive: true
});
關(guān)閉底層socket
,并且停止監(jiān)聽新數(shù)據(jù)。如果提供了回調(diào)函數(shù),它會(huì)被添加為close
事件的監(jiān)聽器。
返回一個(gè)包含socket
地址信息的對(duì)象。對(duì)于UDP socket
,這個(gè)對(duì)象將會(huì)包含address
,family
和port
。
設(shè)置或清除SO_BROADCAST``socket
設(shè)置。當(dāng)這個(gè)選項(xiàng)被設(shè)置,UDP報(bào)文將會(huì)被送至本地接口的廣播地址。
設(shè)置IP_TTL``socket
選項(xiàng)。TTL
的意思是“生存時(shí)間(Time to Live)”,但是在這里的上下文中,它值一個(gè)報(bào)文通過的IP躍點(diǎn)數(shù)。每轉(zhuǎn)發(fā)報(bào)文的路由或網(wǎng)關(guān)都會(huì)遞減TTL
。如果TTL
被一個(gè)路由遞減為0
,它將不再被轉(zhuǎn)發(fā)。改變TTL
值常用于網(wǎng)絡(luò)探測(cè)器或多播。
setTTL()
的參數(shù)是一個(gè)1
到225
之間的躍點(diǎn)數(shù)。多數(shù)系統(tǒng)中的默認(rèn)值為64
。
設(shè)置IP_MULTICAST_TTL``socket
選項(xiàng)。TTL
的意思是“生存時(shí)間(Time to Live)”,但是在這里的上下文中,它值一個(gè)報(bào)文通過的IP躍點(diǎn)數(shù),特別是組播流量。每轉(zhuǎn)發(fā)報(bào)文的路由或網(wǎng)關(guān)都會(huì)遞減TTL
。如果TTL
被一個(gè)路由遞減為0
,它將不再被轉(zhuǎn)發(fā)。
setMulticastTTL()
的參數(shù)是一個(gè)0
到225
之間的躍點(diǎn)數(shù)。多數(shù)系統(tǒng)中的默認(rèn)值為1
。
設(shè)置或清除IP_MULTICAST_LOOP``socket
選項(xiàng)。當(dāng)這個(gè)選項(xiàng)被設(shè)置,組播報(bào)文也將會(huì)在本地接口上接收。
告訴內(nèi)核加入一個(gè)組播分組,通過IP_ADD_MEMBERSHIP``socket
選項(xiàng)。
如果multicastInterface
沒有被指定,那么操作系統(tǒng)將會(huì)嘗試加入成為所有可用的接口的成員。
與addMembership
相反 - 告訴內(nèi)核離開一個(gè)組播分組,通過IP_DROP_MEMBERSHIP``socket
選項(xiàng)。當(dāng)socket
被關(guān)閉或進(jìn)程結(jié)束時(shí),它會(huì)被內(nèi)核自動(dòng)調(diào)用。所以大多數(shù)應(yīng)用不需要親自調(diào)用它。
如果multicastInterface
沒有被指定,那么操作系統(tǒng)將會(huì)嘗試脫離所有可用的接口。
在一個(gè)socket
上調(diào)用unref
將會(huì)在它是事件系統(tǒng)中唯一活躍的socket
時(shí),允許程序退出。如果socket
已經(jīng)被unref
,再次調(diào)用將不會(huì)有任何效果。
返回一個(gè)socket
。
與unref
相反,在一個(gè)先前被unref
的socket
上調(diào)用ref
,那么在它是唯一的剩余的socket
(默認(rèn)行為)時(shí),將不允許程序退出。如果socket
已經(jīng)被ref
,再次調(diào)用將不會(huì)有任何效果。
返回一個(gè)socket
。
更多建議: