互联网的运作,最根本的驱动就是信息的交互,NodeJS 在数据交互这一块做的很带感,异步编程让人很惬意,关于 NodeJS 的数据通信,最基础的两个模块是 NET 和 HTTP,前者是基于 TCP 的封装,后者本质还是 TCP 层,只不过做了比较多的数据封装,我们视之为更高层。

本文先述说 NodeJS 的 NET 模块工作机制,下次再谈一谈 HTTP 模块。

一、服务器和客户端之间的交互

NodeJS 底层支撑是 v8,v8 是用 C++ 编写的一个编译和运行 JavaScript 代码的库,说到 TCP/UDP,写 C/C++ 的童鞋肯定不会感到陌生,在建立 socket 连接的时候,基本都会涉及到相关的知识。

这里先解释下服务器端和客户端之间的一些共性和差异。关于数据交互,我们可以想象成,Server 与 Client 之间建立了一个管道(pipe),这个管道有两个分支,一个是用于发送 S 到 C 的数据,一个是用于发送 C 到 S 的数据。那么这个管道是如何建立的呢?

首先,Server 监听本地的某个端口(所谓端口,可以理解成对外交流的摊铺),Client 很明确自己要跟谁去交流,他去访问 Server 的那个摊铺,于是两者之间就可以沟通了。所以 Server 跟 Client 之间的差异是十分明显的,Server 会监听端口,而 Client 去访问端口。

Unix/Linux 系统跟 windows 有些不同,他可以去监听端口,也可以去监听文件,也就是说他可以把端口和文件都当做对外交流的摊铺。那么 Client 可以通过访问一个文件与 Server 建立起 pipe。

二、Node 如何开启一个 TCP 服务器

在电脑上安装好了 Node 之后,我们就可以引用 Node 提供的模块,Node 内置了很多模块,如文件处理(FireSystem)、控制台(Console)、数据流(Stream)等等,这些我会在以后的文章中提到。建立 TCP 连接需要用到的是 Node 的 NET 模块。使用一个模块十分简单:

var net = require('net');

net 是一个系统模块,也就是安装 Node 之后自带的模块,没必要对他感到畏惧,其实他的内部也是十分简单的:

var Net = function(){};

Net.methodA = function (){};
Net.methodB = function (){}; module.exports = Net;

我们可以简单理解 net 模块的内部实现,他就是一个 Net 类,上面绑定了很多的 methods,require 之后,相当于返回一个 Net 类,此时我们就可以尽情使用 Net 中定义的所有方法和属性了。

Node 中开启一个 TCP 服务器:

// server.js
var net = require('net');
var server = net.createServer(function(socket) { //'connection' listener
console.log('server connected');
socket.on('end', function() {
console.log('server disconnected');
});
socket.on('data', function(){
socket.end('hello\r\n');
});
});
server.listen(8124, function() { //'listening' listener
console.log('server bound');
});

上面这段代码应该很好理解,首先 net.createServer 创建一个 TCP 服务,这个服务绑定(server.listen)在 8124 这个端口上,创建 Server 后我们看到有一个回调函数,这个回调函数的实现方式是怎么样的呢?

net.createServer = function(callback){
// 每次客户端连接都会新建一个 socket
var socket = new Socket();
callback && callback(socket);
};

在调用上面函数的时候传入一个参数,这个参数也是函数,并且接受了 socket ,这个由其他方法构造的一个管道(pipe),他的作用就是用来数据交互的。第一节中我们说到了,pipe 是需要 Client 跟 Server 打招呼才能建立的,如果此刻没有客户端访问 Server,这个 socket 就不会存在了。

三、写一个客户端程序与服务器交互

既然 Socket ,也就是管道(pipe)还没有存在,那肯定是不会存在通讯的,下面来写一个客户端程序:

// client.js
var net = require("net");
var client = net.connect({port: 8124}, function(){
console.log('client connected');
client.write('world!\r\n');
});
client.on('data', function(data) {
console.log(data.toString());
client.end();
});
client.on('end', function() {
console.log('client disconnected');
});

net.connect 顾名思义,就是连接到服务端,第一个参数是对象,设置端口(port)为 8124,也就是我们服务器监听的端口,由于没有设置 host 参数,那默认就是 localhost (本地)。在 Server 中,socket 是管道的一端,而在 client 中,client 本身就是管道的一端,如果是多个客户端连接 Server,Server 会新建多个 socket,每个 socket 对应一个 client。

数据的通信就十分简单了,首先运行服务器程序:

node server.js

此时便会有一个服务器监听 8124 端口,然后打开一个客户端程序:

node client.js

那么两者之间的信息交互就开始了。具体他们是怎么交流的呢?

四、基于事件的哲学

首先我们要说一说 NodeJS 的 EventEmitter 模块。这个模块就是一个事件中心,之前写过相关的内容,可以看看简介版的 EventEmitter,戳我。EventEmitter 也就是如此,可以 on 添加事件到事件池,也可以 trigger 触发事件,当然可以从事件池中删除事件 off。

NET 模块是继承 EventEmitter 的,所以他创建的很多对象可以:

client.on('data', function(data) {
console.log(data.toString());
client.end();
});

如上绑定很多自定义的事件,等到交互中需要信息交流的时候再触发。就拿上面这句代码来说,client 绑定了一个 data 事件,这个事件会在 Server 有信息传过来的时候触发,他所做的工作,先打印传过来的数据,然后 end() 关闭这个管道(pipe)。

JavaScript 是基于事件的一门语言,几乎所有的动作都是由事件驱动的,这个在异步编程中显得十分突出。

五、相关 API 的枚举

Server 除了有 listen 函数外,还有很多的接口:

  • Server.close([callback]),停止监听,那么之前的所有管道也就没有用了。
  • Server.maxConnections,Server 的最大连接数,这个连接数是有上限的(跟系统有关),我们也可以自己设定连接数的最大上限(不超过系统最大连接数)。

  • Server.address(),在 listen 之后可以通过这个函数拿到服务器的相关信息。

// grab a random port.
server.listen(function() {
address = server.address();
console.log("opened server on %j", address);
});

还有 write、end、destroy、pause、resume 等等很多丰富的接口,可以在这里查看详情http://nodejs.org/api/net.html

转 http://www.cnblogs.com/hustskyking/p/nodejs-net-module.html

深入浅出Node.js--数据通讯,NET模块运行机制的更多相关文章

  1. 深入浅出Node.js(一):什么是Node.js

    Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到 ...

  2. 一个月时间整理《深入浅出Node.js》

    今天终于把朴灵老师写的<深入浅出Node.js>给学习完了, 这本书不是一本简单的Node入门书籍,它没有停留在Node介绍或者框架.库的使用层面上,而是从不同的视角来揭示Node自己内在 ...

  3. 读书笔记: 深入浅出node.js

    >> 深入浅出node.js node.js是c++编写的js运行环境 浏览器: 渲染引擎 + js引擎 后端的js运行环境 node.js用google v8引擎,同时提供很多系统级的A ...

  4. 深入浅出Node.js(一):什么是Node.js(转贴)

    以下内容转自:http://www.infoq.com/cn/articles/what-is-nodejs/ 作者:崔康 [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的 ...

  5. 深入浅出Node.js(上)

    (一):什么是Node.js Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟 ...

  6. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

  7. 《深入浅出Node.js》第6章 理解 Buffer

    @by Ruth92(转载请注明出处) 第6章 理解 Buffer ✁ 为什么需要 Buffer? 在 Node 中,应用需要处理网络协议.操作数据库.处理图片.接收上传文件等,在网络流和文件的操作中 ...

  8. 《深入浅出Node.js》第7章 网络编程

    @by Ruth92(转载请注明出处) 第7章 网络编程 Node 只需要几行代码即可构建服务器,无需额外的容器. Node 提供了以下4个模块(适用于服务器端和客户端): net -> TCP ...

  9. node.js(七) 子进程 child_process模块

    众所周知node.js是基于单线程模型架构,这样的设计可以带来高效的CPU利用率,但是无法却利用多个核心的CPU,为了解决这个问题,node.js提供了child_process模块,通过多进程来实现 ...

  10. 《深入浅出node.js(朴灵)》【PDF】下载

    <深入浅出node.js(朴灵)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062563 内容简介 <深入浅出Node. ...

随机推荐

  1. mobile移动网页开发常用代码模板

    index.html <!DOCTYPE HTML> <html> <head> <!--申明当前页面的编码集--> <meta http-equ ...

  2. 8. 利用反射机制, ListArray,intent来实现多Activity的切换

    package com.example.thenewboston; import android.app.ListActivity; import android.content.Intent; im ...

  3. Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain

    笔记六中实现了三种过滤器:字符编码过滤.登录权限过滤.敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤.最后response过滤,而且中间几项过滤的顺序不能动态改变.所 ...

  4. Activity基本跳转

    详细解释:http://blog.csdn.net/xiazdong/article/details/7664757 简单介绍activity的跳转,通过intent实现,详细的注释在代码中.涉及到a ...

  5. ZH奶酪:C语言中malloc()和free()函数解析

    1.malloc()和free()的基本介绍 (1)函数原型及说明 void *malloc(long NumBytes) 该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败 ...

  6. 谈谈node(1)

        node的出现,给了全栈工程师,一个绝佳的机会.   node给我们带来的是更低的硬件成本来完成更高需求以及用户体验感,一台8G内存服务器如果用传统架构,那么最多可驱使4000台同时访问,如果 ...

  7. PHP 表单 - 5(完整表单实例)

    PHP 完整表单实例 本章节将介绍如何让用户在点击"提交(submit)"按钮提交数据前保证所有字段正确输入. PHP - 在表单中确保输入值 在用户点击提交按钮后,为确保字段值是 ...

  8. 20个常用java代码段

    下面是20个非常有用的Java程序片段,希望能对你有用. 1. 字符串有整型的相互转换 String a = String.valueOf(2); //integer to numeric strin ...

  9. webpack 生命周期

    1.插件 可以安装lifecycle-webpack-plugin 插件来查看生命周期信息. 2.webpack流程(生命周期图) 地址:https://img.alicdn.com/tps/TB1G ...

  10. html中文乱码问题的解决

    当我试着用html写代码的时候,发现直接保存的文件用浏览器打开时中文显示是乱码的,所以我找了一些解决方法,可是原因不太明白,所以我也就不解释了,能够自己找找原因,以下提供解决方法: 在写的html的第 ...