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

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

本文地址:http://www.cnblogs.com/hustskyking/p/nodejs-net-module.html,转载请注明源地址。

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

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

六、小结

本来打算写一个聊天室,但是这种简单的代码网络上俯拾皆是,本文目的是说清楚 TCP 连接在服务器和客户端之间的交互过程,深入的话题留到下次谈。

七、参考资料

深入浅出NodeJS——数据通信,NET模块运行机制的更多相关文章

  1. 利用nodejs模块缓存机制创建“全局变量”

    在<深入浅出nodejs>有这样一段(有部分增减): 1.nodejs引入模块分四个步骤 路径分析 文件定位 编译执行 加入内存 2.核心模块部分在node源代码的编译过程中就编译成了二级 ...

  2. 深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制

    深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制 蔡建良 2013-11-14 一. 让我们开始吧 通过命令行来执行 1) 进行命令窗口: cmd 2) 进入resourc ...

  3. 深入浅出话VC++(1)——Windows程序内部运行机制

    一.引言 要想熟练掌握Windows应用程序的开发,首先需要理解Windows平台下程序运行的内部机制,然而在.NET平台下,创建一个Windows桌面程序,只需要简单地选择Windows窗体应用程序 ...

  4. 大熊君大话NodeJS之------Net模块

    一,开篇分析 从今天开始,我们来深入具体的模块学习,这篇文章是这个系列(大熊君大话NodeJS)文章的第三篇,前两篇主要是以理论为主,相信大家在前两篇的学习中, 对NodeJS也有一个基本的认识,没事 ...

  5. 大熊君大话NodeJS之------Http模块

    一,开篇分析 首先“Http”这个概念大家应该比较熟悉了,它不是基于特定语言的,是一个通用的应用层协议,不同语言有不同的实现细节,但是万变不离其宗,思想是相同的, NodeJS作为一个宿主运行环境,以 ...

  6. 关于Nodejs的多进程模块Cluster

    关于Nodejs的多进程模块Cluster   前述 我们都知道nodejs最大的特点就是单进程.无阻塞运行,并且是异步事件驱动的.Nodejs的这些特性能够很好的解决一些问题,例如在服务器开发中,并 ...

  7. PHP的运行机制与原理(底层) [转]

    说到php的运行机制还要先给大家介绍php的模块,PHP总共有三个模块:内核.Zend引擎.以及扩展层:PHP内核用来处理请求.文件流.错误处理等相关操作:Zend引擎(ZE)用以将源文件转换成机器语 ...

  8. Nodejs中cluster模块的多进程共享数据问题

    Nodejs中cluster模块的多进程共享数据问题 前述 nodejs在v0.6.x之后增加了一个模块cluster用于实现多进程,利用child_process模块来创建和管理进程,增加程序在多核 ...

  9. 微信小程序剖析【下】:运行机制

    在上一篇<微信小程序「官方示例代码」浅析[上]>中,我们只是简单的罗列了一下代码,这一篇,让我们来玩点刺激的——就是看看IDE的代码,了解它是怎么运行的. 还好微信的开发团队在软件工程的实 ...

随机推荐

  1. JQuery实现图片轮播效果源码

    ======================整体结构======================== <div class="banner"> <ul class ...

  2. Maven仓库

    http://search.maven.org/#search%7Cga%7C1%7C

  3. Java学习1 - java 历史

    Sun的Java语言开发小组成立于1991年,其目的是开拓消费类电子产品市场,例如:交互式电视,烤面包箱等.Sun内部人员把这个项目称为 Green,那时World Wide Web还在图纸上呢.该小 ...

  4. 对&quot;QQGame-大家来找茬&quot;的辅助工具的改进

    [前言]最近在博客园首页上看到有“大家来找茬”这个游戏(此游戏为找出两个相近图片的不同点)外挂的相关帖子,所以这里我也翻看了我之前(2009年5月)的写的一个简单的辅助程序(采用 VC6 开发的).我 ...

  5. Hexo - 快速,轻量,强大的 Node.js 博客框架

    Hexo 是一个快速,轻量,强大的 Node.js 博客框架.带给你难以置信的编译速度,瞬间生成静态文件:支持 Markdown,甚至可以在 Hexo 中集合 Octopress 插件:只需要一个命令 ...

  6. 【BZOJ】3456: 城市规划

    http://www.lydsy.com/JudgeOnline/problem.php?id=3456 题意:求n个点的无向连通图的方案.(n<=130000) #include <bi ...

  7. CodeForces 686B-Little Robber Girl&#39;s Zoo

    题目: 有n头数量的动物,开始它们站在一排,它们之间有高度差,所以需要将它们进行交换使得最终形成一个不减的序列,求它们交换的区间.交换的规则:一段区间[l, r]将l与l+1.l+2与l+3..... ...

  8. MVC + EF + Bootstrap 2 权限管理系统入门级(附源码)

    MVC .EF 学习有大半年了,用的还不是很熟练,正好以做这样一个简单的权限管理系统作为学习的切入点,还是非常合适的. 开发环境: VS 2013 + Git + MVC 5 + EF 6 Code ...

  9. 一个SpringMVC简单Demo中出现的错误

    最近在学springmvc 一个简答的Springmvc配置包括如下步骤: 1.在 web.xml 文件中配置 DispatcherServlet (该中央控制器相当于 MVC 模式中的 C),还可以 ...

  10. WCF 入门(29)

    前言 最近工作比较忙,加了会班就不想再写东西了,就想洗洗睡. 但是这个视频真的不能断,不能像过去一样写了几集就停了. 现在公司在做一个MVC框架的项目,话说已经一年没有写MVC了,重新上手的感觉还可以 ...