创建UDP服务器

TCP的可靠保证,是它的三次握手机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,所以不可靠。不过UDP的速度是TCP比不了的,而且UDP的反应速度更快,QQ就是用UDP协议传输的,HTTP是用TCP协议传输的,前面介绍的几节都是建立在TCP协议之上的,当然UDP也是有其优势,简单了解一下协议的概念即可。

node.js也提供了UDP协议支持的模块,通过var dgram = require('dgram')可以加载该模块。

可以这么说建立UDP客户端和服务器端是一样的,因为互相之间只是简单的知道对方的ip和端口号,然后把数据丢过去而已。

先开发个程序,这个程序客户端可以发信息,服务器端接收到后打印出来。然后再详细讲解。

// 服务器代码
var dgram = require("dgram");
var server = dgram.createSocket('udp4');
server.bind(8080);

server.on("message",function(msg,rinfo){
    console.log(msg.toString())
})
// 客户端代码
var dgram = require("dgram");
var client = dgram.createSocket("udp4");
process.stdin.on("data",function(data){
    client.send(data,0,data.length,8080,"localhost");
});

运行服务器端然后启动客户端,客户端输入字符串然后回车,服务器会打印出客户端发来的信息。

客户端通过udp.createSocket建立了一个socket然后接收到终端输入的信息后,通过send方法把信息发送到服务器端。

服务器端监听到信息后,激发message事件,事件监听器打印出信息。

下面讲解udp模块的各个使用方法。googog

dgram.createSocket(type, [callback])

这个方法可以创建一个UDP的socket对象。

type参数,可以是 udp4或udp6 对应ipv4和ipv6,现在还是以ipv4为主,所以都选用 udp4。

callback[可选]参数,是message事件的监听器。

return 返回的是一个socket对象,这个socket对象不是net.Socket类型,而是dgram.Socket对象。

看例子:

var udp = require("dgram");
var serverSocket = udp.createSocket('udp4',function(msg){
    console.log(msg.toString())
});
serverSocket.bind(8080);

dgram.Socket

通过dgram.createSocket方法得到的dgram.Socket对象,区别于net.Socket,这个socket是专门为了UDP协议重新设计重写的,下面深入研究一下dgram.Socket。

'message'事件

message事件监听器会接收到两个参数 callback(msg,rinfo),msg表示接收到的数据,是Buffer类型。rinfo是一个json对象,rinfo类似如下信息 { address: '127.0.0.1', family: 'IPv4', port: 59615, size: 5 } 。 address表示发送信息主机的ip地址,port表示发送信息主机的端口,size表示信息的byte数量。看下面例子:

var udp = require("dgram");
var socket = udp.createSocket('udp4');
socket.on("message",function(msg,rinfo){
    console.log(msg.toString())
});
socket.bind(8080);

'listening'事件

listening事件是当socket准备好接收信息时会触发该事件。看下面代码:

socket.on("listening",function(){
    // ... ...
})

'close'事件

当调用socket.close() 时激发close事件。

error 事件

当socket内部发生错误时,会激发error事件。

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

这个方法是发送信息的方法。

buf参数表示发送的信息,是Buffer类型。

offset参数是发送buf的起始位置。

length参数是发送buf的长度。

port参数表示发送到目标主机端口。

address参数表示发送到目标主机的地址。

callback(err,bytes)[可选]回调函数,但发送完成后调用这个回调函数,err表示错误信息,bytes表示发送出去的字节数量。

socket.address()

得到本地socket信息,信息类似于 { address: '0.0.0.0', family: 'IPv4', port: 8080 }

但调用这个方法必须是激发listening事件之后,否则会抛出异常。

socket.setBroadcast(flag)

这个方法是设置是否UDP广播,简单说就是发送一条信息,本地局域网内的UDP主机能收到这条消息,广播地址是 255.255.255.255 。

注意,调用这个方法也必须是激发listening事件之后,否则会抛出异常。

看下面代码:

// 接收方
var udp = require("dgram");
var socket = udp.createSocket('udp4',function(msg){
   console.log(msg.toString())
});
socket.bind(8080);
// 广播端
var udp = require("dgram");
var client = udp.createSocket("udp4",function(){});
client.on("listening",function(){
    client.setBroadcast(true);
})
process.stdin.on("data",function(data){
    client.send(data,0,data.length,8080,"255.255.255.255");
});

广播端发送的信息会被局域网内8080端口接收端接收到信息。

socket.setTTL(ttl)

ttl 是 1~255的一个值,单位是毫秒ms。ttl是IP协议包中的一个值,它告诉网络,数据包在网络中的时间是否太长而应被丢弃。说白了就是一个信息发送出去,数据在传输过程中ttl会递减,等到0时,就会死亡,当然在死亡之前数据到达目标主机就算成功了,默认是64。