Node.js开发入门—UDP编程

news/2024/5/18 13:16:49 标签: node.js, udp, socket, angularjs, mongodb

Node.js也提供了UDP编程的能力,相关类库在“dgram”模块里。

与TCP不同,UDP是无连接的,不保障数据的可靠性,不过它的编程更为简单,有时候我们也需要它。比如做APP的统计或者日志或者流媒体,很多流媒体协议都会用到UDP,网上一搜一大堆。

使用UDP,如果你要发送数据,只需要知道对方的主机名(地址)和端口号,扔一消息过去即可。至于对方收不收得到,听天由命了。这就是数据报服务,类似快递或邮件。

我们这次来介绍一下Node.js里的UDP编程,我会提供一个UDP版本的echoServer和echoClient。

udp编程的一般模型">UDP编程的一般模型

客户端和服务端分开来说。

先说服务端吧。

服务端

作为UDP服务器,要想接收来自客户端的消息,在Node.js里,大体有这么几步:

  1. 导入dgram模块
  2. 创建socket(套接字)
  3. 处理message事件
  4. 绑定端口

后面我们的echoServer示例可以看到具体的代码。

客户端

客户端UDP编程就更简单了,一下几步,就可以了:

  1. 导入dgram模块
  2. 创建socket(套接字)
  3. 发送消息

当然有时你也可能希望客户端也能收到服务消息,比如你发一个消息给服务端,希望服务端反馈,那此时就也需要处理message事件和绑定端口。具体就看我们的echoClient示例了。

API介绍

要使用dgram模块,只需这样:

var dgram = require('dgram');

引入了dgram后,就可以使用它提供的方法createSocket来创建套接字了。createSocket方法返回一个dgram.Socket对象,这个对象提供了一系列的方法和事件。

dgram.Socket的bind方法把socket和一个端口绑定到一起,比如echo服务的端口是7,那下面的代码片段就创建了一个socket并绑定到端口7上:

var dgram = require('dgram');
var serverSocket = dgram.createSocket('udp4');
serverSocket.bind(7);

在有消息到达时dgram.Socket会发射message事件,我们监听这个事件就可以处理消息:

serverSocket.on('message', function(msg, rinfo){
  ...
});

message事件对应的回调函数有两个参数,一个是Buffer对象msg,代表客户端发送过来的数据。一个是rinfo,携带了远程主机的信息,rinfo.address是远程主机的地址,rinfo.port是远程主机的端口。

dgram.Socket还有“error”、“close”、“listening”等事件,参考在线文档:https://nodejs.org/api/dgram.html。

要发送数据,可以调用dgram.send方法,就像下面这样:

var msg = new Buffer('Hello Server');
serverSocket.send(msg, 0, msg.length, 7, "127.0.0.1");

示例

echoServerUdp.js实现了我们的echoServer示例,代码如下:

var dgram = require('dgram');

var serverSocket = dgram.createSocket('udp4');

serverSocket.on('message', function(msg, rinfo){
  console.log('recv %s(%d bytes) from client %s:%d\n', msg, msg.length, rinfo.address, rinfo.port);

  //echo to client
  serverSocket.send(msg, 0, msg.length, rinfo.port, rinfo.address);
});

//    err - Error object, https://nodejs.org/api/errors.html
serverSocket.on('error', function(err){
  console.log('error, msg - %s, stack - %s\n', err.message, err.stack);
});

serverSocket.on('listening', function(){
  console.log("echo server is listening on port 7.");
})

serverSocket.bind(7);

echoClientUdp.js实现了echo客户端,代码如下:

var dgram = require('dgram');

var clientSocket = dgram.createSocket('udp4');

var messages = [
  'Hello, Echo Server.',
  'Are you OK?',
  'I am happy.',
  'A little panda found a pumpkin.'
];

var index = 0;

function sendMsg(){//send to server
  var msg = messages[index];
  index = index + 1;
  if(index == messages.length){
    index = 0;
  }
  clientSocket.send(msg, 0, msg.length, 7, "localhost");
}

//start a timer to send message to echoServer
setInterval(sendMsg, 1000);

clientSocket.on('message', function(msg, rinfo){
  console.log('recv %s(%d) from server\n', msg, msg.length);
});

clientSocket.on('error', function(err){
  console.log('error, msg - %s, stack - %s\n', err.message, err.stack);
});

clientSocket.bind(54321);

看起来客户端比服务端还要复杂一些,这是因为作为echo客户端,我需要显示服务端发送的消息,所以,也需要监听到一个端口(在示例中是54321)。另外,我还要不断发送数据给服务端,所以用setInterval启动了一个周期性定时器,循环发送一个字符串数组内的消息。

setInterval是Node.js的global对象提供的方法,用来启动一个周期性定时器,原型如下:

setInterval(cb, ms)

第一个参数是定时器触发时会执行的回调函数,第二个参数是定时器的周期,单位是毫秒。我们的示例中,每隔1000毫秒发送一条消息给服务器。

setInterval返回一个代表定时器的值,你可以把它传递给clearInterval来取消对应的定时器。

另外echoServer和echoClient在处理dgram.Socket的error事件时,用到了Error对象,文档在这里:https://nodejs.org/api/errors.html。

好啦,代码就这样,可以打开两个命令行窗口,分别执行“node echoServerUdp.js”和“node echoClientUdp.js”来观察效果。


其它文章:

  • Node.js开发入门——使用http访问外部世界
  • Node.js开发入门——套接字(socket)编程
  • Node.js开发入门——notepad++ for Node.js
  • Node.js开发入门——使用对话框ngDialog
  • Node.js开发入门——引入UIBootstrap
  • Node.js开发入门——用MongoDB改造LoginDemo
  • Node.js开发入门——MongoDB与Mongoose
  • Node.js开发入门——使用cookie保持登录
  • Node.js开发入门——使用AngularJS内置服务
  • Node.js开发入门——Angular简单示例
  • Node.js开发入门——使用AngularJS
  • Node.js开发入门——使用jade模板引擎
  • Node.js开发入门——Express里的路由和中间件
  • Node.js开发入门——Express安装与使用
  • Node.js开发入门——HTTP文件服务器
  • Node.js开发入门——HelloWorld再分析
  • Node.js开发入门——环境搭建与HelloWorld

http://www.niftyadmin.cn/n/818105.html

相关文章

项目进度估算难题

(本文曾发表于《程序员》2015.09.B) 程序员要面临的挑战千千万,项目进度评估是有史以来就存在而且到现在也没有完美解决的重量级问题。 我曾发过一张暴漫,描述项目行进的过程,叫做“软件项目9步神曲”。我还专门写了…

程序员被人喜欢的13点原因

林语堂有提到不被人喜欢的十种原因: 一、腰有十文钱必振衣作响。 二、每与人言必谈及贵戚。 三、遇美人必急索登床。 四、见到问路之人必作傲睨之态。 五、与朋友相聚便喋喋高吟其酸腐诗文。 六、头已花白却喜唱艳曲。 七、施人一小惠便广布于众。 八、与人交…

Node.js开发入门—语音合成示例

出于项目需要,搞了一个语音合成(TTS)的小示例,使用的是OKVoice。 我想在PC上测试,OKVoice的快速接入API可以实现我的目的,文档在这里:http://dev.okvoice.com/file.php。 直接上代码吧&#x…

Node.js开发入门—Buffer用法详解

Node.js中有一个Buffer类,必须要介绍一下,因为我们在使用Node.js做服务端开发时,http、tcp、udp、文件io等等类型的操作,都会用到Buffer,离开它基本没办法玩儿下去。 Buffer是什么 JavaScript里的String对象&#xf…

怎样新学一门技术

(本文曾发表于《程序员》2015.10.A期) 因为公司缺一个系Web管理系统的开发,我决定挑一个技术栈来学习一下,然后自己来写。我选择了Node.jsExpressAngulaJSMongoDB这一条技术栈,花了将近两周的时间,做了很多…

Node.js开发入门—Stream用法详解

Stream是Node.js中非常重要的一个模块,应用广泛。一个流是一个具备了可读、可写或既可读又可写能力的接口,通过这些接口,我们可以和磁盘文件、套接字、HTTP请求来交互,实现数据从一个地方流动到另一个地方的功能。 所有的流都实现…

月薪3万的程序员都避开了哪些坑

程序员薪水有高有低,有的人一个月可能拿30K、50K,有的人可能只有2K、3K。同样有五年工作经验的程序员,可能一个人每月拿20K,一个拿5K。是什么因素导致了这种差异?我特意总结了容易导致薪水低的九大行为表现&#xff0c…

如何快速定位自己热爱的工作

我前几天发了篇文章,“月薪3万的程序员都避开了哪些坑”,有很多朋友看了,反馈很多,我汇总了一下,有两方面的意见比较突出: 文中说的都是大道理,妇幼皆知,知易行难不喜欢开发&#x…