首页 web前端 js教程 Nodejs学习笔记之NET模块_node.js

Nodejs学习笔记之NET模块_node.js

May 16, 2016 pm 04:20 PM
net模块 nodejs

一,开篇分析

从今天开始,我们来深入具体的模块学习,这篇文章是这个系列文章的第三篇,前两篇主要是以理论为主,相信大家在前两篇的学习中,

对NodeJS也有一个基本的认识,没事!!!趁热打铁,让我们继续将NodeJS进行到底,好了废话不多说,直接进入今天的主题 “Net模块” ,那么”Net“应该如何理解那?

它是做什么用的那?(Net模块可用于创建Socket服务器或Socket客户端。NodeJS 的数据通信,最基础的两个模块是 Net 和 Http,前者是基于 Tcp 的封装,后者本质还是 Tcp 层,只不过做了比较多的数据封装,我们视为表现层)。

这里参考一下NodeJS “http.js” 中的源码:

从图中不难看出 HttpServer继承了Net类,具有了相关的通信能力,做了比较多的数据封装,我们视为更高级的表现层。

扩展知识(以下是“inherits”的源码):

复制代码 代码如下:

exports.inherits = function(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};

功能是实现继承复用。

刚才做了一个简要的概述,里面有一些常用的概念,这里做个简短的概念普及介绍:

  (1),TCP/IP------TPC/IP协议是传输层协议,主要解决数据如何在网络中传输。

  (2),Socket------socket则是对TCP/IP协议的封装和应用(程序层面)。

  (3),Http------HTTP是应用层协议,主要解决如何包装数据。

  (4),网络七层模型------物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

  总结一下:Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API)。

  从而形成了我们知道的一些最基本的函数接口,比如Create、Listen、Connect、Accept、Send、Read和Write等等。

  TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口

  实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口。

二,体验一把

好了,概念我们也有了,来个例子:

1,建立server.js

复制代码 代码如下:

var net = require('net') ;
var server = net.createServer(function(c) { // Connection监听器
  console.log("服务器已连接") ;
  c.on("end", function() {
    console.log("服务器已断开") ;
  }) ;
  c.write("Hello,Bigbear !\r\n") ;
  c.pipe(c) ;
}) ;
server.listen(8124, function() { // Listening监听器
  console.log("服务器已绑定") ;
}) ;

2,建立client.js

复制代码 代码如下:

var net = require('net') ;
var client = net.connect({
    port: 8124
},function(){ // connect监听器
  console.log("客户端已连接") ;
  client.write('Hello,Baby !\r\n') ;
});
client.on("data", function(data) {
  console.log(data.toString()) ;
  client.end() ;
});
client.on("end", function(){
  console.log("客户端断开连接") ;
}) ;

分析一下:

服务端------net.createServer创建一个 TCP 服务,这个服务绑定(server.listen)在 8124 这个端口上,创建 Server 后我们看到有一个回调函数,

在调用上面函数的时候传入一个参数,这个参数也是函数,并且接受了 socket ,这个由其他方法构造的一个管道(pipe),他的作用就是用来数据交互的。

pipe 是需要 Client 跟 Server 打招呼才能建立的,如果此刻没有客户端访问 Server,这个 socket 就不会存在了。

客户端------net.connect顾名思义,就是连接到服务端,第一个参数是对象,设置端口(port)为 8124,也就是我们服务器监听的端口,由于没有设置 host 参数,那默认就是 localhost (本地)。

在 Server 中,socket 是管道的一端,而在 client 中,client 本身就是管道的一端,如果是多个客户端连接 Server,Server 会新建多个 socket,每个 socket 对应一个 client。

运行结果:

三,案例引入

(1),下面代码仅仅是服务器向客户端输出一段文本,完成服务端到客户端的单向通讯。

复制代码 代码如下:

//  Sever --> Client 的单向通讯
var net = require('net');
var chatServer = net.createServer();
chatServer.on('connection', function(client) {
  client.write('Hi!\n'); // 服务端向客户端输出信息,使用 write() 方法
  client.write('Bye!\n');
  client.end(); // 服务端结束该次会话
});
chatServer.listen(9000);

Telnet测试一下:telnet127.0.0.1:9000

执行 telnet后,与服务点连接,反馈 Hi! Bye! 的字符,并立刻结束服务端程序终止连接。

如果我们要服务端接到到客户端的信息?

可以监听 server.data 事件并且不要中止连接(否则会立刻结束无法接受来自客户端的消息)。

(2),监听 server.data 事件并且不要中止连接(否则会立刻结束无法接受来自客户端的消息)。

复制代码 代码如下:

// 在前者的基础上,实现 Client --> Sever 的通讯,如此一来便是双向通讯
var net = require('net');
var chatServer = net.createServer(),   
    clientList = [];
chatServer.on('connection', function(client) {
  // JS 可以为对象自由添加属性。这里我们添加一个 name 的自定义属性,用于表示哪个客户端(客户端的地址+端口为依据)
  client.name = client.remoteAddress + ':' + client.remotePort; 
  client.write('Hi ' + client.name + '!\n'); 
  clientList.push(client); 
  client.on('data', function(data) {   
     broadcast(data, client);// 接受来自客户端的信息 
  });
});
function broadcast(message, client) { 
    for(var i=0;i       if(client !== clientList[i]) {     
        clientList[i].write(client.name + " says " + message);   
      } 
    }
}
chatServer.listen(9000);

上面是不是一个完整功能的代码呢?我们说还有一个问题没有考虑进去:那就是一旦某个客户端退出,却仍保留在 clientList里面,这明显是一个空指针。

(3),处理clientList

复制代码 代码如下:

chatServer.on('connection', function(client) {
  client.name = client.remoteAddress + ':' + client.remotePort
  client.write('Hi ' + client.name + '!\n');
  clientList.push(client)
  client.on('data', function(data) {
    broadcast(data, client)
  })
  client.on('end', function() {
    clientList.splice(clientList.indexOf(client), 1); // 删除数组中的制定元素。
  })
})

NodeTCPAPI已经为我们提供了 end 事件,即客户端中止与服务端连接的时候发生。

(4),优化broadcast

复制代码 代码如下:

function broadcast(message, client) {
  var cleanup = []
  for(var i=0;i     if(client !== clientList[i]) {
      if(clientList[i].writable) { // 先检查 sockets 是否可写
        clientList[i].write(client.name + " says " + message)
      } else {
        cleanup.push(clientList[i]) // 如果不可写,收集起来销毁。销毁之前要 Socket.destroy() 用 API 的方法销毁。
        clientList[i].destroy()
      }
    }
  }  //Remove dead Nodes out of write loop to avoid trashing loop index
  for(i=0;i     clientList.splice(clientList.indexOf(cleanup[i]), 1)
  }
}

注意的是一旦 “end” 没有被触发,会出现异常,所以才做优化工作。

(5),NetAPI中还提供一个 error 事件,用于捕捉客户端的异常

复制代码 代码如下:

client.on('error', function(e) {
  console.log(e);
});

四,总结一下

1,理解开篇的相关概念

2,认识Http与Net模块之间的关系

3,结合本文的例子,查阅相关api去实践

4,socket客户端与服务器端之间的通信思想

5,有兴趣可以完善一下那个聊天室的例子

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

nodejs和vuejs区别 nodejs和vuejs区别 Apr 21, 2024 am 04:17 AM

Node.js 是一种服务器端 JavaScript 运行时,而 Vue.js 是一个客户端 JavaScript 框架,用于创建交互式用户界面。Node.js 用于服务器端开发,如后端服务 API 开发和数据处理,而 Vue.js 用于客户端开发,如单页面应用程序和响应式用户界面。

nodejs是后端框架吗 nodejs是后端框架吗 Apr 21, 2024 am 05:09 AM

Node.js 可作为后端框架使用,因为它提供高性能、可扩展性、跨平台支持、丰富的生态系统和易于开发等功能。

nodejs怎么连接mysql数据库 nodejs怎么连接mysql数据库 Apr 21, 2024 am 06:13 AM

要连接 MySQL 数据库,需要遵循以下步骤:安装 mysql2 驱动程序。使用 mysql2.createConnection() 创建连接对象,其中包含主机地址、端口、用户名、密码和数据库名称。使用 connection.query() 执行查询。最后使用 connection.end() 结束连接。

nodejs中的全局变量有哪些 nodejs中的全局变量有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全局变量:全局对象:global核心模块:process、console、require运行时环境变量:__dirname、__filename、__line、__column常量:undefined、null、NaN、Infinity、-Infinity

nodejs安装目录里的npm与npm.cmd文件有什么区别 nodejs安装目录里的npm与npm.cmd文件有什么区别 Apr 21, 2024 am 05:18 AM

Node.js 安装目录中有两个与 npm 相关的文件:npm 和 npm.cmd,区别如下:扩展名不同:npm 是可执行文件,npm.cmd 是命令窗口快捷方式。Windows 用户:npm.cmd 可以在命令提示符下使用,npm 只能从命令行运行。兼容性:npm.cmd 特定于 Windows 系统,npm 跨平台可用。使用建议:Windows 用户使用 npm.cmd,其他操作系统使用 npm。

nodejs和java的差别大吗 nodejs和java的差别大吗 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差异在于设计和特性:事件驱动与线程驱动:Node.js 基于事件驱动,Java 基于线程驱动。单线程与多线程:Node.js 使用单线程事件循环,Java 使用多线程架构。运行时环境:Node.js 在 V8 JavaScript 引擎上运行,而 Java 在 JVM 上运行。语法:Node.js 使用 JavaScript 语法,而 Java 使用 Java 语法。用途:Node.js 适用于 I/O 密集型任务,而 Java 适用于大型企业应用程序。

nodejs是后端开发语言吗 nodejs是后端开发语言吗 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一种后端开发语言。它用于后端开发,包括处理服务器端业务逻辑、管理数据库连接和提供 API。

nodejs和java选哪个 nodejs和java选哪个 Apr 21, 2024 am 04:40 AM

Node.js 和 Java 在 Web 开发中各有优劣,具体选择取决于项目要求。Node.js 擅长实时应用程序、快速开发和微服务架构,而 Java 则在企业级支持、性能和安全性方面占优。

See all articles