穩定性: 3 - 穩定
調用 require('dgram')
,可以使用數據報文 sockets(Datagram sockets)。
重要提醒: dgram.Socket#bind()
的行為在 v0.10 做了改動 ,它總是異步的。如果你的代碼像下面的一樣:
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');
});
type
字符串. 'udp4' 或 'udp6'callback
函數. 附加到 message
事件的監聽器。可選參數。創建指定類型的數據報文(datagram) Socket。有效類型是udp4
和 udp6
接受一個可選的回調,會被添加為 message
的監聽事件。
如果你想接收數據報文(datagram)可以調用 socket.bind()
。socket.bind()
將會綁定到所有接口("all interfaces")的隨機端口上( udp4
和 udp6
sockets 都適用)。你可以通過socket.address().address
和 socket.address().port
獲取地址和端口。
options
對象callback
函數. 給 message
事件添加事件監聽器.參數 options
必須包含 type
值(udp4
或 udp6
),或可選的 boolean 值 reuseAddr
。
當 reuseAddr
為 true 時, socket.bind()
將會重用地址,即使另一個進程已經綁定 socket。 reuseAddr
默認為 false
。
回調函數為可選參數,作為 message
事件的監聽器。
如果你想接受數據報文(datagram),可以調用 socket.bind()
。socket.bind()
將會綁定到所有接口( "all interfaces" )地址的隨機端口上( udp4
和 udp6
sockets 都適用)。你可以通過socket.address().address
和 socket.address().port
獲取地址和端口。
報文數據 Socket 類封裝了數據報文(datagram) 函數。必須通過 dgram.createSocket(...)
函數創建。
msg
緩存對象. 消息。rinfo
對象. 遠程地址信息。當 socket 上新的數據報文(datagram)可用的時候,會觸發這個事件。msg
是一個緩存,rinfo
是一個包含發送者地址信息的對象
socket.on('message', function(msg, rinfo) {
console.log('Received %d bytes from %s:%d\n',
msg.length, rinfo.address, rinfo.port);
});
當 socket 開始監聽數據報文(datagram)時觸發。在 UDP socket 創建時觸發。
當 socket 使用 close()
關閉時觸發。在這個 socket 上不會觸發新的消息事件。
exception
Error 對象當發生錯誤時觸發。
buf
緩存對象 或 字符串. 要發送的消息。offset
整數. 消息在緩存中得偏移量。length
整數. 消息的比特數。port
整數. 端口的描述。address
字符串. 目標的主機名或 IP 地址。callback
函數. 當消息發送完畢的時候調用。可選。對于 UDP socket,必須指定目標端口和地址。 address
參數可能是字符串,它會被 DNS 解析。
如果忽略地址或者地址是空字符串,將使用 '0.0.0.0'
或 '::0'
替代。依賴于網絡配置,這些默認值有可能行也可能不行。
如果 socket 之前沒被調用 bind
綁定,則它會被分配一個隨機端口并綁定到所有接口( "all interfaces" )地址(udp4
sockets 的'0.0.0.0'
, udp6
sockets 的'::0'
)
回調函數可能用來檢測 DNS 錯誤,或用來確定什么時候重用 buf
對象。注意,DNS 查詢會導致發送tick延遲。通過回調函數能確認數據報文(datagram)是否已經發送的
考慮到多字節字符串情況,偏移量和長度是字節長度byte length,而不是字符串長度。
下面的例子是在 localhost
上發送一個 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();
});
關于 UDP 數據報文(datagram) 尺寸
IPv4/v6
數據報文(datagram)的最大長度依賴于MTU
(Maximum Transmission Unit)和 Payload Length
的長度。
Payload Length
內容為 16 位寬,它意味著 Payload 的最大字節說不超過 64k,其中包括了頭信息和數據(65,507 字節 = 65,535 ? 8 字節 UDP 頭 ? 20 字節 IP 頭);對于環回接口(loopback interfaces)這是真的,但對于多數主機和網絡來說不太現實。
MTU
能支持數據報文(datagram)的最大值(以目前鏈路層技術來說)。對于任何連接,IPv4
允許的最小值為 68
的 MTU
,推薦值為 576
(通常推薦作撥號應用的 MTU
),無論他們是完整接收還是碎片接收。
對于 IPv6
,MTU
的最小值為 1280
字節,最小碎片緩存大小為 1500
字節。16 字節實在是太小,所以目前鏈路層一般最小 MTU
大小為 1500
。
我們不可能知道一個包可能進過的每個連接的MTU。通常發送一個超過接收端 MTU 大小的數據報文(datagram)會失效。(數據包會被悄悄的拋棄,不會通知發送端數據包沒有到達接收端)。
port
整數address
字符串, 可選callback
沒有參數的函數, 可選。綁定時會調用回調。對于 UDP socket,在一個端口和可選地址上監聽數據報文(datagram)。如果沒有指定地點,系統將會參數監聽所有的地址。綁定完畢后,會觸發 "listening" 事件,并會調用傳入的回調函數。指定監聽事件和回調函數非常有用。
一個綁定了的數據報文 socket 會保持 node 進程運行來接收數據。
如果綁定失敗,會產生錯誤事件。極少數情況(比如綁定一個關閉的 socket)。這個方法會拋出一個錯誤。
以下是 UDP 服務器監聽端口 41234 的例子:
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
{對象} - 必需. 有以下的屬性:port
{Number} - 必需.address
{字符串} - 可選.exclusive
{Boolean} - 可選.callback
{函數} - 可選.options
的可選參數port
和 address
,以及可選參數 callback
,好像在調用 socket.bind(port, [address], [callback])。
如果 exclusive
是 false
(默認),集群進程將會使用相同的底層句柄,允許連接處理共享的任務。當exclusive
為 true
時,句柄不會共享,嘗試共享端口也會失敗。監聽 exclusive
端口的例子如下:
socket.bind({
address: 'localhost',
port: 8000,
exclusive: true
});
關閉底層 socket 并且停止監聽數據。
返回一個包含套接字地址信息的對象。對于 UDP socket,這個對象會包含address
, family
和 port
。
flag
Boolean設置或清除 SO_BROADCAST
socket 選項。設置這個選項后,UDP 包可能會發送給一個本地的接口廣播地址。
ttl
整數設置 IP_TTL
socket 選項。 TTL 表示生存時間(Time to Live),但是在這個上下文中它指的是報文允許通過的 IP 躍點數。各個轉發報文的路由器或者網關都會遞減 TTL。如果 TTL 被路由器遞減為0,則它將不會被轉發。改變 TTL 的值通常用于網絡探測器或多播。
setTTL()
的參數為 1 到 255 的躍點數。多數系統默認值為 64.
ttl
整數設置 IP_MULTICAST_TTL
socket 選項. TTL 表示生存時間(Time to Live),但是在這個上下文中它指的是報文允許通過的 IP 躍點數。 各個轉發報文的路由器或者網關都會遞減 TTL。如果 TTL 被路由器遞減為0,則它將不會被轉發。改變 TTL 的值通常用于網絡探測器或多播。
setMulticastTTL()
的參數為 1 到 255 的躍點數。多數系統默認值為 1.
flag
Boolean設置或清空 IP_MULTICAST_LOOP
socket 選項。設置完這個選項后,當該選項被設置時,組播報文也會被本地接口收到。
multicastAddress
字符串multicastInterface
字符串, 可選告訴內核加入廣播組,選項為 IP_ADD_MEMBERSHIP
socket
如果沒有指定 multicastInterface
,操作系統會給所有可用的接口添加關系。
multicastAddress
字符串multicastInterface
字符串, 可選和 addMembership
相反 - 用 IP_DROP_MEMBERSHIP
選項告訴內核離開廣播組 。如果沒有指定 multicastInterface
,操作系統會移除所有可用的接口關系。
在 socket 上調用 unref
允許程序退出,如果這是在事件系統中唯一的活動 socket。如果 socket 已經 unref
,再次調用 unref
將會無效。
和 unref
相反,如果這是唯一的 socket,在一個之前被 unref 了的 socket 上調用 ref 將不會讓程序退出(缺省行為)。如果一個 socket 已經被 ref,則再次調用 ref 將會無效。