深刻淺出Node.js--數據通信,NET模塊運行機制

互聯網的運做,最根本的驅動就是信息的交互,NodeJS 在數據交互這一塊作的很帶感,異步編程讓人很愜意,關於 NodeJS 的數據通訊,最基礎的兩個模塊是 NET 和 HTTP,前者是基於 TCP 的封裝,後者本質仍是 TCP 層,只不過作了比較多的數據封裝,咱們視之爲更高層。html

本文先述說 NodeJS 的 NET 模塊工做機制,下次再談一談 HTTP 模塊。node

1、服務器和客戶端之間的交互

NodeJS 底層支撐是 v8,v8 是用 C++ 編寫的一個編譯和運行 JavaScript 代碼的庫,說到 TCP/UDP,寫 C/C++ 的童鞋確定不會感到陌生,在創建 socket 鏈接的時候,基本都會涉及到相關的知識。編程

這裏先解釋下服務器端和客戶端之間的一些共性和差別。關於數據交互,咱們能夠想象成,Server 與 Client 之間創建了一個管道(pipe),這個管道有兩個分支,一個是用於發送 S 到 C 的數據,一個是用於發送 C 到 S 的數據。那麼這個管道是如何創建的呢?windows

首先,Server 監聽本地的某個端口(所謂端口,能夠理解成對外交流的攤鋪),Client 很明確本身要跟誰去交流,他去訪問 Server 的那個攤鋪,因而二者之間就能夠溝通了。因此 Server 跟 Client 之間的差別是十分明顯的,Server 會監聽端口,而 Client 去訪問端口。api

Unix/Linux 系統跟 windows 有些不一樣,他能夠去監聽端口,也能夠去監聽文件,也就是說他能夠把端口和文件都當作對外交流的攤鋪。那麼 Client 能夠經過訪問一個文件與 Server 創建起 pipe。服務器

2、Node 如何開啓一個 TCP 服務器

在電腦上安裝好了 Node 以後,咱們就能夠引用 Node 提供的模塊,Node 內置了不少模塊,如文件處理(FireSystem)、控制檯(Console)、數據流(Stream)等等,這些我會在之後的文章中提到。創建 TCP 鏈接須要用到的是 Node 的 NET 模塊。使用一個模塊十分簡單:dom

var net = require('net');

net 是一個系統模塊,也就是安裝 Node 以後自帶的模塊,不必對他感到畏懼,其實他的內部也是十分簡單的:異步

var Net = function(){};

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

module.exports = Net;

咱們能夠簡單理解 net 模塊的內部實現,他就是一個 Net 類,上面綁定了不少的 methods,require 以後,至關於返回一個 Net 類,此時咱們就能夠盡情使用 Net 中定義的全部方法和屬性了。socket

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 就不會存在了。

3、寫一個客戶端程序與服務器交互

既然 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

那麼二者之間的信息交互就開始了。具體他們是怎麼交流的呢?

4、基於事件的哲學

首先咱們要說一說 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 是基於事件的一門語言,幾乎全部的動做都是由事件驅動的,這個在異步編程中顯得十分突出。

5、相關 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

相關文章
相關標籤/搜索