Node.js用户数据报dgram模块的使用

 2015年08月13日    2806     声明


用户数据报协议(User Datagram Protocol,UDP)和TCP协议一样,都在传输层,位于IP协议之上。TCP是一个面向连接的协议,它在网络节点之间提供可靠有序的数据流。与TCP不同,UDP允许你向其它主机发送消息(数据报),而不需要提前建立连接。由于UDP的无状态性,不用像TCP那样面向连接,所以UDP相对轻量,这对于服务器响应来向大量客户端的查询非常有用。与TCP相比,UDP的另一个优势是支持消息的广播和多多播。在Node.js中,dgram模块用来支持和实现UDP用户数据报协议。

  1. 构建UDP服务器
  2. 创建UDP客户端


1. 构建UDP服务器

构建一个UDP Socket套接字对象使用dgram.createSocket()方法,这个方法返回的Socket套接字对象,可以监听一个网络端口,从而启动一个UDP服务器,createSocket有下面两种形式:

dgram.createSocket(type[, callback]):创建指定类型的用户数据报(datagram) Socket

  • type:用户数据报类型,可以是:'udp4''udp6'
  • callback:回调函数,会被附加为message事件的监听器。

构建一个UDP服务器使用dgram.createSocket(),这个方法会启动一个UDP用户数据报监听并返回一个UDP Socket套接字对象,createSocket有下面两种形式:

dgram.createSocket(options[, callback]):通过options创建UDP Socket用户数据报(datagram)套接字对象

  • options:创建UDP Socket的参数对象,该对象包括以下参数
    • type:必选,可以是:'udp4''udp6'
    • reuseAddr:可选,可是:truefalse。 默认为false,当为 true 时,socket.bind() 将会重用地址,即使该socket套接字对象已经被另一个进程绑定。
  • callback:回调函数,会被附加为message事件的监听器。

如果想接收数据报可以调用 socket.bind方法。socket.bind()方法在所有用网络接口随机选一个端口(udp4udp6 皆是),绑定后可以通过 socket.address().addresssocket.address().port来取得地址和端口。

var dgram=require('dgram');
var server=dgram.createSocket('udp4');

//message事件监听
server.on('message', function(message, rinfo) {
    console.log('收到消息:%s ,来自于 %s:%d ',message.toString('utf8'), rinfo.address, rinfo.port);
    //将收到的消息回发给客户端
    server.send(message,0,message.length,rinfo.port,rinfo.address);
});

//listening事件监听
server.on('listening',function(){
    var address=server.address();
    console.log('listening on:'+address.address+':'+address.port)
});

//绑定3333端口
server.bind(3333);

在上面的示例代码中,创建一个UDP的服务端,这个服务端会监听3333端口。


2. 创建UDP客户端

dgram.createSocket()方法返回UDP Socket套接字对象,可以通过端口监听实现一个UDP服务器。其返回的UDP Socket套接字对象又可以做一个UDP客户端,这个客户端可以与UDP服务器进行交互,实现服务器与客户端数据的收发。

//启动格式:node 文件名 host port
var host = process.argv[2];
var port = parseInt(process.argv[3],10);

var dgram = require('dgram');
var client = dgram.createSocket('udp4');

process.stdin.resume();

//通过stdin接受用户输入数据
process.stdin.on('data', function(data){
    client.send(data, 0, data.length, port, host);
})

var message=new Buffer('hello UDP, from itbilu.com');
client.send(message, 0, message.length, port, host, function (err, bytes) {
    //数据发送监听器
    if(err) {throw err;}
});

//监听message事件,接收数据
client.on('message', function(msg){
    console.log('收到了UDP服务端消息:', msg.toString());
    // client.close();
})

上面的客户端代码会从stdin标准备输入中接受用户输入的数据,并将数据发送到UDP服务器,收到服务器数据后会在控制台打印收到的数据。

上面的UDP客户端代码被保存为udpClient.js,启动服务端代码后,运行客户端代码:node udpClient.js localhost 3333,运行效果如下:

$ node udpClient.js localhost 3333
收到了UDP服务端消息: hello UDP, from itbilu.com
hello server  
收到了UDP服务端消息: hello server