UDN-企业互联网技术人气社区

板块导航

浏览  : 438
回复  : 2

[Nodejs] 使用net模块和Readline模块实现Socket通信

[复制链接]
genie1003的头像 楼主
  Node.js的socket通信和C++、Java的非常相像,学过这两种语言的socket通信的同学可以很快就掌握好Node.js的socket通信。下面我们以实现一个Echo服务器的服务端和客户端为目的,学习一下Node.js的socket通信。

  所谓的Echo服务器指的是这样一种服务器:客户端发送一条消息给服务端,服务端就把这条消息原封不动地返回给客户端。

  服务端

  服务端的实现分为三步: - 通过createServer创建一个server服务端 - 使用server的listen方法监听指定端口,等待客户端接入 - 通过socket对象来监听data、close等事件,用以完成与客户端的交互

  下面是服务端代码:
  1. /**
  2. * Created by Administrator on 2015/9/8.
  3. */

  4. var net = require('net');  
  5. // 服务器IP
  6. var HOST = '127.0.0.1';  
  7. // 端口号
  8. var PORT = 7001;

  9. // 创建一个TCP服务器实例,调用listen函数开始监听指定端口
  10. // 传入net.createServer()的回调函数将作为”connection“事件的处理函数
  11. // 在每一个“connection”事件中,该回调函数接收到的socket对象是唯一的
  12. net.createServer(function(sock) {

  13.     // 获得了一个socket连接,将客户端输出来
  14.     console.log('CONNECTED: ' +
  15.         sock.remoteAddress + ':' + sock.remotePort);

  16.     // 为这个socket实例添加一个"data"事件处理函数
  17.     sock.on('data', function(data) {
  18.         console.log('DATA ' + sock.remoteAddress + ': ' + data);
  19.         // 回发该数据,客户端将收到来自服务端的数据,实现ECHO服务器
  20.         sock.write('' + data );
  21.     });

  22.     // 为这个socket实例添加一个"close"事件处理函数
  23.     sock.on('close', function(data) {
  24.         console.log('CLOSED: ' +
  25.             sock.remoteAddress + ' ' + sock.remotePort);
  26.     });

  27. }).listen(PORT, HOST);

  28. console.log('Server listening on ' + HOST +':'+ PORT);
复制代码

  使用createListener的时候会传入一个回调函数,当客户端连接上服务端时调用。在回调函数里,完成了对data、close事件的监听。

  • data事件:当客户端有消息发送过来时触发此事件
  • close事件:当客户端断开连接时触发此事件

  客户端

  因为要实现的是Echo服务器,所以自然要实现输入与输出,这里,我使用了上一篇介绍的Readline模块来实现控制台的输入与输出,对这一模块不太熟悉的同学,可以先去看一下 Readline模块的介绍 。

  与服务端相似,客户端的实现也分为三步: - 创建一个socket - 连接上指定IP指定端口号的服务端 - 监听data、close等事件完成与服务端的交互

  客户端代码如下:
  1. /**
  2. * Created by Administrator on 2015/9/8.
  3. */

  4. var net = require('net');  
  5. var readline = require('readline');

  6. // 创建Readline接口
  7. rl = readline.createInterface(process.stdin, process.stdout);

  8. var HOST = '127.0.0.1';  
  9. var PORT = 7001;

  10. var client = new net.Socket();  
  11. client.connect(PORT, HOST, function() {  
  12.     console.log('CONNECTED TO: ' + HOST + ':' + PORT);
  13.     // 连接建立后,开始执行命令行输入
  14.     rl.setPrompt('Test> ');
  15.     rl.prompt();
  16. });

  17. // 为客户端添加“data”事件处理函数
  18. // data是服务器发回的数据
  19. client.on('data', function(data) {  
  20.    // 输出服务器端传来的消息
  21.    console.log(""+data);
  22.    rl.prompt();
  23. });

  24. // 为客户端添加“close”事件处理函数
  25. client.on('close', function() {  
  26.     console.log('Connection closed');
  27.     process.exit(0);
  28. });

  29. rl.on('line', function(line) {  
  30.     switch(line.trim()) {
  31.         case 'close':
  32.             rl.close();
  33.             return;
  34.     }
  35.     client.write(line.trim());
  36.     rl.prompt();
  37. }).on('close', function() {
  38.     console.log('Good bye!');
  39.     client.end();
  40. });
复制代码

  这里应该注意,客户端socket监听了data和close事件、我们的输入输出模块也监听了它们自己的line、close事件,前者是client变量,后者是rl变量,要区别开来。

  当我们输入close后,会发生以下过程 1. line事件里调用Readline.close()触发了Readline的close事件;

  2. 在Readline的close事件里,调用client.end()结束客户端,从而触发客户端的close事件;

  3. 客户端的close事件监听器里执行程序退出操作 process.exit(0).

  通信结果

  客户端:
2.png
  服务端:
1.png
  通信涉及三个过程: 1. 客户端接收用户输入信息后将发往服务端;

  2. 服务端接收客户端传来信息后将原封返回给客户端;

  3. 客户端接收服务端信息后将其显示出来。

相关帖子

发表于 2017-1-5 10:27:57 | 显示全部楼层
我是被标题吸引进来的
使用道具 举报

回复

发表于 2017-1-9 05:43:08 | 显示全部楼层
js框架越来越火了, 不过本人还是喜欢原生的好, 自己写类库, 自己来封装,用着方便。。。。
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部