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