Node.js API详解之 dgram模块用法实例分析
本文实例讲述了Node.jsAPI详解之dgram模块用法。分享给大家供大家参考,具体如下:
Node.jsAPI详解之dgram
dgram模块提供了UDP数据包socket的实现。
使用以下方式引用:
constdgram=require('dgram');
dgram.createSocket(options[,callback])
说明:
创建一个dgram.Socket对象.一旦创建了套接字,调用socket.bind()会指示套接字开始监听数据报消息。
如果address和port没传给socket.bind(),
那么这个方法会把这个套接字绑定到“全部接口”地址的一个随机端口(这适用于udp4和udp6套接字)。
绑定的地址和端口可以通过socket.address().address和socket.address().port来获取
options:
type:套接字族.必须是‘udp4'或‘udp6'.必需填.
reuseAddr:若设置为truesocket.bind(),则会重用地址,即时另一个进程已经在其上面绑定了一个套接字。默认是false.
recvBufferSize:设置SO_RCVBUF套接字值。
sendBufferSize:设置SO_SNDBUF套接字值。
lookup:惯常的查询函数.默认是dns.lookup()。
callback:为‘message'事件绑定一个监听器。可选。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket({type:'udp4'},()=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.bind(41234); //服务器监听0.0.0.0:41234
dgram.createSocket(type[,callback])
说明:
创建一个特定type的dgram.Socket对象。type参数是udp4或udp6。
可选传一个回调函数,作为‘message'事件的监听器。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4',()=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.bind(41234);
dgram.Socket类
说明:
dgram.Socket对象是一个封装了数据包函数功能的EventEmitter。
dgram.Socket实例是由dgram.createSocket()创建的。
创建dgram.Socket实例不需要使用new关键字。
socket.bind([port][,address][,callback])
说明:
对于UDPsocket,该方法会令dgram.Socket在指定的port和可选的address上监听数据包信息。
若port未指定或为0,操作系统会尝试绑定一个随机的端口。
若address未指定,操作系统会尝试在所有地址上监听。
绑定完成时会触发一个'listening'事件,并会调用callback方法。
注意,同时监听'listening'事件和在socket.bind()方法中传入callback参数并不会带来坏处,但也不是很有用。
一个被绑定的数据包socket会令Node.js进程保持运行以接收数据包信息。
若绑定失败,一个'error'事件会被触发。在极少数的情况下(例如尝试绑定一个已关闭的socket),一个Error会被抛出。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4',()=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.bind(41234,()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); }); //服务器监听0.0.0.0:41234
socket.bind(options[,callback])
说明:
options:{port:”,address:”,exclusive:”}
对于UDPsocket,该方法会令dgram.Socket在指定的port和可选的address上监听数据包信息。
若port未指定或为0,操作系统会尝试绑定一个随机的端口。
若address未指定,操作系统会尝试在所有地址上监听。
绑定完成时会触发一个'listening'事件,并会调用callback方法。
在配合cluster模块使用dgram.Socket对象时,options对象可能包含一个附加的exclusive属性。
当exclusive被设为false(默认值)时,集群工作单元会使用相同的socket句柄来共享连接处理作业。
当exclusive被设为true时,该句柄将不会被共享,而尝试共享端口则会造成错误。
一个绑定的数据报socket会使Node.js进程持续运行以接受数据报消息。
如果绑定失败,一个‘error'事件会产生。在极少数情况下(例如尝试绑定一个已经关闭的socket),一个Error可能抛出。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4',()=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.bind({port:41234},()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); }); //服务器监听0.0.0.0:41234
listening事件
说明:
当一个socket开始监听数据包信息时,'listening'事件将被触发。
该事件会在创建UDPsocket之后被立即触发。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4',()=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.on('listening',()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); }); server.bind({port:41234}); //服务器监听0.0.0.0:41234
error事件
说明:
当有任何错误发生时,'error'事件将被触发。
事件发生时,事件处理函数仅会接收到一个Error参数。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4'); server.on('error',(err)=>{ console.log(`服务器异常:\n${err.stack}`); server.close(); }); server.on('message',(msg,rinfo)=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.on('listening',()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); }); server.bind({port:41234});
message事件
说明:
当有新的数据包被socket接收时,'message'事件会被触发。
msg和rinfo会作为参数传递到该事件的处理函数中。
msg:消息
rinfo:远程地址信息
address:发送方地址
family:地址类型(‘IPv4'or‘IPv6')
port:发送者端口
size:消息大小
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4'); server.on('message',(msg,rinfo)=>{ console.log(`服务器收到:${msg}来自${rinfo.address}:${rinfo.port}`); }); server.on('listening',()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); }); server.bind({port:41234});
socket.getRecvBufferSize()
说明:
socket接收到的字节大小。
demo:
server.on('message',(msg,rinfo)=>{ console.log(`服务器收到字节数:${socket.getRecvBufferSize()}`); });
socket.setRecvBufferSize(size)
说明:
设置SO_RCVBUF套接字选项。设置最大的套接字接收缓冲字节。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4'); server.setRecvBufferSize(1024); server.on('message',(msg,rinfo)=>{ console.log(`服务器收到字节数:${socket.getRecvBufferSize()}`); }); server.bind({port:41234});
socket.send(msg,[offset,length,]port[,address][,callback])
说明:
在socket上发送一个数据包。目标port和address须被指定。
msg参数包含了要发送的消息。根据消息的类型可以有不同的做法。
如果msg是一个Buffer或Uint8Array,则offset和length指定了消息在Buffer中对应的偏移量和字节数。
如果msg是一个String,那么它会被自动地按照utf8编码转换为Buffer。
对于包含了多字节字符的消息,offset和length会根据对应的bytelength进行计算,而不是根据字符的位置。
如果msg是一个数组,那么offset和length必须都不能被指定。
address参数是一个字符串。若address的值是一个主机名,则DNS会被用来解析主机的地址。
若address未提供或是非真值,则'127.0.0.1'(用于udp4socket)或'::1'(用于udp6socket)会被使用。
若在之前socket未通过调用bind方法进行绑定,socket将会被一个随机的端口号赋值并绑定到“所有接口”的地址上(对于udp4socket是'0.0.0.0',对于udp6socket是'::0')。
可以指定一个可选的callback方法来汇报DNS错误或判断可以安全地重用buf对象的时机。
注意,在Node.js事件循环中,DNS查询会对发送造成至少1tick的延迟。
确定数据包被发送的唯一方式就是指定callback。若在callback被指定的情况下有错误发生,该错误会作为callback的第一个参数。
若callback未被指定,该错误会以'error'事件的方式投射到socket对象上。
偏移量和长度是可选的,但如其中一个被指定则另一个也必须被指定。
另外,他们只在第一个参数是Buffer或Uint8Array的情况下才能被使用。
demo:
constdgram=require('dgram'); constserver=dgram.createSocket('udp4'); constbuf1=Buffer.from('Some'); constbuf2=Buffer.from('bytes'); server.on('error',(err)=>{ console.log(`服务器异常:\n${err.stack}`); server.close(); }); server.on('message',(msg,rinfo)=>{ console.log(`服务器收到字节数:${socket.getRecvBufferSize()}`); }); server.on('listening',()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); }); server.send([buf1,buf2],8080,'localhost'); server.bind({port:41234});
socket.getSendBufferSize()
说明:
socket发送的字节大小。
demo:
server.send([buf1,buf2],8080,'localhost',()=>{ console.log('发送消息字节数:',server.getSendBufferSize()); });
socket.setSendBufferSize(size)
说明:
设置SO_SNDBUF套接字选项。设置最大的套接字发送缓冲字节。
demo:
constsocket=dgram.createSocket('udp6'); socket.bind(1234,()=>{ socket.setSendBufferSize(1024); });
socket.unref()
说明:
默认情况下,绑定一个socket会在socket运行时阻止Node.js进程退出。
socket.unref()方法用于将socket从维持Node.js进程的引用列表中解除。
可以使用socket.ref()再次激活。
socket.unref()方法返回一个对socket的引用,所以可以链式调用。
demo:
constdgram=require('dgram'); constsocket=dgram.createSocket('udp6'); socket.bind(1234,()=>{ socket.unref(); });
socket.ref()
说明:
默认情况下,绑定一个socket会在socket运行时阻止Node.js进程退出。
socket.unref()方法用于将socket从维持Node.js进程的引用列表中解除。
socket.ref()方法用于将socket重新添加到这个引用列表中,并恢复其默认行为。
多次调用socket.ref()不会有额外的作用。
socket.ref()方法返回一个对socket的引用,所以可以链式调用。
demo:
constdgram=require('dgram'); constsocket=dgram.createSocket('udp6'); socket.bind(1234,()=>{ socket.unref(); socket.ref() });
socket.close([callback])
说明:
关闭该socket并停止监听其上的数据。
如果提供了一个回调函数,它就相当于为'close'事件添加了一个监听器。
demo:
constdgram=require('dgram'); constsocket=dgram.createSocket('udp6'); socket.bind(1234); socket.close(()=>{ console.log('socket已关闭'); }); //socket已关闭
close事件
说明:
‘close'事件将在使用close()关闭一个socket之后触发。
该事件一旦触发,这个socket上将不会触发新的'message'事件。
demo:
constdgram=require('dgram'); constsocket=dgram.createSocket('udp6'); socket.bind(1234); socket.on('close',()=>{ console.log('socket已关闭'); }) socket.close(); //socket已关闭
socket.address()
说明:
返回一个包含socket地址信息的对象。
对于UDPsocket,该对象将包含address、family和port属性。
demo:
server.on('listening',()=>{ constaddress=server.address(); console.log(`服务器监听${address.address}:${address.port}`); });
socket.addMembership(multicastAddress[,multicastInterface])
说明:
通知内核将multicastAddress和multicastInterface提供的多路传送集合通过IP_ADD_MEMBERSHIP这个socket选项结合起来。
若multicastInterface参数未指定,操作系统将会选择一个接口并向其添加成员。
要为所有可用的接口添加成员,可以在每个接口上调用一次addMembership方法。
socket.dropMembership(multicastAddress[,multicastInterface])
说明:
引导内核通过IP_DROP_MEMBERSHIP这个socket选项删除multicastAddress指定的多路传送集合。
当socket被关闭或进程被终止时,该方法会被内核自动调用,所以大多数的应用都不用自行调用该方法。
若multicastInterface未指定,操作系统会尝试删除所有可用接口上的成员。
socket.setBroadcast(flag)
说明:
设置或清除SO_BROADCASTsocket选项。
当设置为true,UDP包可能会被发送到一个本地接口的广播地址
socket.setMulticastLoopback(flag)
说明:
设置或清除IP_MULTICAST_LOOPsocket选项。当设置为true,多播数据包也将在本地接口接收。
socket.setMulticastTTL(ttl)
说明:
设置IP_MULTICAST_TTL套接字选项。一般来说,TTL表示”生存时间”。这里特指一个IP数据包传输时允许的最大跳步数,尤其是对多播传输。
当IP数据包每向前经过一个路由或网关时,TTL值减1,若经过某个路由时,TTL值被减至0,便不再继续向前传输。
传给socket.setMulticastTTL()的参数是一个范围为0-255的跳步数。大多数系统的默认值是1,但是可以变化。
socket.setTTL(ttl)
说明:
设置IP_TTL套接字选项。一般来说,TTL表示”生存时间”,这里特指一个IP数据包传输时允许的最大跳步数。
当IP数据包每向前经过一个路由或网关时,TTL值减1,若经过某个路由时,TTL值被减至0,便不再继续向前传输。
比较有代表性的是,为了进行网络情况嗅探或者多播而修改TTL值。
传给socket.setTTL()的参数是一个范围为0-255的跳步数。大多数系统的默认值是1,但是可以变化。
希望本文所述对大家node.js程序设计有所帮助。