IO.js UDP/Datagram

2018-11-28 22:36 更新

穩(wěn)定度: 2 - 穩(wěn)定

數(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');
});

dgram.createSocket(type[, callback])

  • type String. 'udp4''udp6',兩者之一
  • callback Function. 可選,會被添加為message事件的監(jiān)聽器
  • Returns: 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().addresssocket.address().port中獲取地址和端口。

dgram.createSocket(options[, callback])

  • options Object
  • callback Function. 會被添加為message事件的監(jiān)聽器
  • Returns: socket對象

options對象必須包含一個type屬性,可是udp4或udp6。還有一個可選的reuseAddr布爾值屬性。

當(dāng)reuseAddrtrue時,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().addresssocket.address().port中獲取地址和端口。

Class: dgram.Socket

dgram.Socket類封裝了數(shù)據(jù)報的功能。它必須被dgram.createSocket(...)創(chuàng)建。

Event: 'message'

  • msg Buffer object. 消息
  • rinfo Object. 遠程地址信息

當(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);
});

Event: 'listening'

當(dāng)一個socket開始監(jiān)聽數(shù)據(jù)報時觸發(fā)。在UDP socket被創(chuàng)建時觸發(fā)。

Event: 'close'

在一個socket通過close()被關(guān)閉時觸發(fā)。這個socket中不會再觸發(fā)新的message事件。

Event: 'error'

  • exception Error object

當(dāng)錯誤發(fā)生時觸發(fā)。

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

  • buf Buffer object or string. 要被發(fā)送的信息。
  • offset Integer. 信息在buffer里的初始偏移位置。
  • length Integer. 信息的字節(jié)數(shù)。
  • port Integer. 目標(biāo)端口。
  • address String. 目標(biāo)主機或IP地址。
  • callback Function. 可選,當(dāng)信息被發(fā)送后調(diào)用。

對于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é)字符的考慮,offsetlength將會根據(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();
});
UDP數(shù)據(jù)報大小的注意事項

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ù)沒有到達已定的接收方)。

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

  • port Integer
  • address String, 可選
  • callback Function 可選,沒有參數(shù)。當(dāng)綁定完畢后觸發(fā)。

對于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

socket.bind(options[, callback])

  • options Object - 必選,支持以下屬性:

  • port Number - 必須
  • address String - 可選
  • exclusive Boolean - 可選

  • callback Function - 可選

optionsprotaddress屬性,以及可選的回調(diào)函數(shù),與socket.bind(port, [address], [callback])中它們的表現(xiàn)一致。

exclusivefalse(默認(rèn)),那么集群的工作進程將會使用相同的底層句柄,允許共享處理連接的職責(zé)。當(dāng)為true時,句柄不被共享,企圖共享端口會導(dǎo)致一個錯誤。一個監(jiān)聽一個exclusive端口的例子:

socket.bind({
  address: 'localhost',
  port: 8000,
  exclusive: true
});

socket.close([callback])

關(guān)閉底層socket,并且停止監(jiān)聽新數(shù)據(jù)。如果提供了回調(diào)函數(shù),它會被添加為close事件的監(jiān)聽器。

socket.address()

返回一個包含socket地址信息的對象。對于UDP socket,這個對象將會包含address,familyport。

socket.setBroadcast(flag)

  • flag Boolean

設(shè)置或清除SO_BROADCAST``socket設(shè)置。當(dāng)這個選項被設(shè)置,UDP報文將會被送至本地接口的廣播地址。

socket.setTTL(ttl)

  • ttl Integer

設(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ù)是一個1225之間的躍點數(shù)。多數(shù)系統(tǒng)中的默認(rèn)值為64。

socket.setMulticastTTL(ttl)

  • ttl Integer

設(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ù)是一個0225之間的躍點數(shù)。多數(shù)系統(tǒng)中的默認(rèn)值為1。

socket.setMulticastLoopback(flag)

  • flag Boolean

設(shè)置或清除IP_MULTICAST_LOOP``socket選項。當(dāng)這個選項被設(shè)置,組播報文也將會在本地接口上接收。

socket.addMembership(multicastAddress[, multicastInterface])

  • multicastAddress String
  • multicastInterface String, 可選

告訴內(nèi)核加入一個組播分組,通過IP_ADD_MEMBERSHIP``socket選項。

如果multicastInterface沒有被指定,那么操作系統(tǒng)將會嘗試加入成為所有可用的接口的成員。

socket.dropMembership(multicastAddress[, multicastInterface])

  • multicastAddress String
  • multicastInterface String, 可選

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.unref()

在一個socket上調(diào)用unref將會在它是事件系統(tǒng)中唯一活躍的socket時,允許程序退出。如果socket已經(jīng)被unref,再次調(diào)用將不會有任何效果。

返回一個socket。

socket.ref()

unref相反,在一個先前被unrefsocket上調(diào)用ref,那么在它是唯一的剩余的socket(默認(rèn)行為)時,將不允許程序退出。如果socket已經(jīng)被ref,再次調(diào)用將不會有任何效果。

返回一個socket。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號