欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nodejs學(xué)習(xí)筆記之NET模塊

 更新時間:2015年01月13日 10:23:36   投稿:hebedich  
之前兩篇文章基本上都是給我們介紹的nodejs的理論基礎(chǔ),今天我們來點干貨,先從NET模塊開始講起吧。

一,開篇分析

從今天開始,我們來深入具體的模塊學(xué)習(xí),這篇文章是這個系列文章的第三篇,前兩篇主要是以理論為主,相信大家在前兩篇的學(xué)習(xí)中,

對NodeJS也有一個基本的認(rèn)識,沒事!?。〕脽岽蜩F,讓我們繼續(xù)將NodeJS進(jìn)行到底,好了廢話不多說,直接進(jìn)入今天的主題 “Net模塊” ,那么”Net“應(yīng)該如何理解那?

它是做什么用的那?(Net模塊可用于創(chuàng)建Socket服務(wù)器或Socket客戶端。NodeJS 的數(shù)據(jù)通信,最基礎(chǔ)的兩個模塊是 Net 和 Http,前者是基于 Tcp 的封裝,后者本質(zhì)還是 Tcp 層,只不過做了比較多的數(shù)據(jù)封裝,我們視為表現(xiàn)層)。

這里參考一下NodeJS “http.js” 中的源碼:

從圖中不難看出 HttpServer繼承了Net類,具有了相關(guān)的通信能力,做了比較多的數(shù)據(jù)封裝,我們視為更高級的表現(xiàn)層。

擴(kuò)展知識(以下是“inherits”的源碼):

復(fù)制代碼 代碼如下:

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

功能是實現(xiàn)繼承復(fù)用。

剛才做了一個簡要的概述,里面有一些常用的概念,這里做個簡短的概念普及介紹:

 ?。?),TCP/IP------TPC/IP協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸。

 ?。?),Socket------socket則是對TCP/IP協(xié)議的封裝和應(yīng)用(程序?qū)用?。

 ?。?),Http------HTTP是應(yīng)用層協(xié)議,主要解決如何包裝數(shù)據(jù)。

 ?。?),網(wǎng)絡(luò)七層模型------物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會話層、表示層和應(yīng)用層。

  總結(jié)一下:Socket是對TCP/IP協(xié)議的封裝,Socket本身并不是協(xié)議,而是一個調(diào)用接口(API)。

  從而形成了我們知道的一些最基本的函數(shù)接口,比如Create、Listen、Connect、Accept、Send、Read和Write等等。

  TCP/IP只是一個協(xié)議棧,就像操作系統(tǒng)的運行機制一樣,必須要具體實現(xiàn),同時還要提供對外的操作接口

  實際上,傳輸層的TCP是基于網(wǎng)絡(luò)層的IP協(xié)議的,而應(yīng)用層的HTTP協(xié)議又是基于傳輸層的TCP協(xié)議的,而Socket本身不算是協(xié)議,就像上面所說,它只是提供了一個針對TCP或者UDP編程的接口。

二,體驗一把

好了,概念我們也有了,來個例子:

1,建立server.js

復(fù)制代碼 代碼如下:

var net = require('net') ;
var server = net.createServer(function(c) { // Connection監(jiān)聽器
  console.log("服務(wù)器已連接") ;
  c.on("end", function() {
    console.log("服務(wù)器已斷開") ;
  }) ;
  c.write("Hello,Bigbear !\r\n") ;
  c.pipe(c) ;
}) ;
server.listen(8124, function() { // Listening監(jiān)聽器
  console.log("服務(wù)器已綁定") ;
}) ;

2,建立client.js

復(fù)制代碼 代碼如下:

var net = require('net') ;
var client = net.connect({
    port: 8124
},function(){ // connect監(jiān)聽器
  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("客戶端斷開連接") ;
}) ;

分析一下:

服務(wù)端------net.createServer創(chuàng)建一個 TCP 服務(wù),這個服務(wù)綁定(server.listen)在 8124 這個端口上,創(chuàng)建 Server 后我們看到有一個回調(diào)函數(shù),

在調(diào)用上面函數(shù)的時候傳入一個參數(shù),這個參數(shù)也是函數(shù),并且接受了 socket ,這個由其他方法構(gòu)造的一個管道(pipe),他的作用就是用來數(shù)據(jù)交互的。

pipe 是需要 Client 跟 Server 打招呼才能建立的,如果此刻沒有客戶端訪問 Server,這個 socket 就不會存在了。

客戶端------net.connect顧名思義,就是連接到服務(wù)端,第一個參數(shù)是對象,設(shè)置端口(port)為 8124,也就是我們服務(wù)器監(jiān)聽的端口,由于沒有設(shè)置 host 參數(shù),那默認(rèn)就是 localhost (本地)。

在 Server 中,socket 是管道的一端,而在 client 中,client 本身就是管道的一端,如果是多個客戶端連接 Server,Server 會新建多個 socket,每個 socket 對應(yīng)一個 client。

運行結(jié)果:

三,案例引入

(1),下面代碼僅僅是服務(wù)器向客戶端輸出一段文本,完成服務(wù)端到客戶端的單向通訊。

復(fù)制代碼 代碼如下:

//  Sever --> Client 的單向通訊
var net = require('net');
var chatServer = net.createServer();
chatServer.on('connection', function(client) {
  client.write('Hi!\n'); // 服務(wù)端向客戶端輸出信息,使用 write() 方法
  client.write('Bye!\n');
  client.end(); // 服務(wù)端結(jié)束該次會話
});
chatServer.listen(9000);

Telnet測試一下:telnet127.0.0.1:9000

執(zhí)行 telnet后,與服務(wù)點連接,反饋 Hi! Bye! 的字符,并立刻結(jié)束服務(wù)端程序終止連接。

如果我們要服務(wù)端接到到客戶端的信息?

可以監(jiān)聽 server.data 事件并且不要中止連接(否則會立刻結(jié)束無法接受來自客戶端的消息)。

(2),監(jiān)聽 server.data 事件并且不要中止連接(否則會立刻結(jié)束無法接受來自客戶端的消息)。

復(fù)制代碼 代碼如下:

// 在前者的基礎(chǔ)上,實現(xiàn) Client --> Sever 的通訊,如此一來便是雙向通訊
var net = require('net');
var chatServer = net.createServer(),   
    clientList = [];
chatServer.on('connection', function(client) {
  // JS 可以為對象自由添加屬性。這里我們添加一個 name 的自定義屬性,用于表示哪個客戶端(客戶端的地址+端口為依據(jù))
  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<clientList.length;i+=1) {   
      if(client !== clientList[i]) {     
        clientList[i].write(client.name + " says " + message);   
      } 
    }
}
chatServer.listen(9000);

上面是不是一個完整功能的代碼呢?我們說還有一個問題沒有考慮進(jìn)去:那就是一旦某個客戶端退出,卻仍保留在 clientList里面,這明顯是一個空指針。

(3),處理clientList

復(fù)制代碼 代碼如下:

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); // 刪除數(shù)組中的制定元素。
  })
})

NodeTCPAPI已經(jīng)為我們提供了 end 事件,即客戶端中止與服務(wù)端連接的時候發(fā)生。

(4),優(yōu)化broadcast

復(fù)制代碼 代碼如下:

function broadcast(message, client) {
  var cleanup = []
  for(var i=0;i<clientList.length;i+=1) {
    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<cleanup.length;i+=1) {
    clientList.splice(clientList.indexOf(cleanup[i]), 1)
  }
}

注意的是一旦 “end” 沒有被觸發(fā),會出現(xiàn)異常,所以才做優(yōu)化工作。

(5),NetAPI中還提供一個 error 事件,用于捕捉客戶端的異常

復(fù)制代碼 代碼如下:

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

四,總結(jié)一下

1,理解開篇的相關(guān)概念

2,認(rèn)識Http與Net模塊之間的關(guān)系

3,結(jié)合本文的例子,查閱相關(guān)api去實踐

4,socket客戶端與服務(wù)器端之間的通信思想

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

相關(guān)文章

  • Node.js實現(xiàn)簡單聊天服務(wù)器

    Node.js實現(xiàn)簡單聊天服務(wù)器

    Node.js 是一個基于Chrome JavaScript運行時建立的一個平臺, 用來方便地搭建快速的,易于擴(kuò)展的網(wǎng)絡(luò)應(yīng)用,今天我們來探討下,如何使用node.js實現(xiàn)簡單的聊天服務(wù)器
    2014-06-06
  • node.js中g(shù)et和post接口教程

    node.js中g(shù)et和post接口教程

    這篇文章主要介紹了node.js中g(shù)et和post接口學(xué)習(xí),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • npm?i報錯以及解決方案實戰(zhàn)案例

    npm?i報錯以及解決方案實戰(zhàn)案例

    npm在前端開發(fā)流程中提供了非常完善的自動化工具鏈,但是同樣由于其復(fù)雜性導(dǎo)致有很多奇奇怪怪的問題,下面這篇文章主要給大家介紹了關(guān)于npm?i報錯以及解決方案的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • nodejs異步編程基礎(chǔ)之回調(diào)函數(shù)用法分析

    nodejs異步編程基礎(chǔ)之回調(diào)函數(shù)用法分析

    這篇文章主要介紹了nodejs異步編程基礎(chǔ)之回調(diào)函數(shù)用法,結(jié)合具體實例形式分析了阻塞與非阻塞形式下回調(diào)函數(shù)具體功能、使用技巧,需要的朋友可以參考下
    2018-12-12
  • Node.js API詳解之 Error模塊用法實例分析

    Node.js API詳解之 Error模塊用法實例分析

    這篇文章主要介紹了Node.js API詳解之 Error模塊用法,結(jié)合實例形式分析了Node.js API中Error模塊相關(guān)功能、函數(shù)、用法及操作注意事項,需要的朋友可以參考下
    2020-05-05
  • 使用Node.js配合Nginx實現(xiàn)高負(fù)載網(wǎng)絡(luò)

    使用Node.js配合Nginx實現(xiàn)高負(fù)載網(wǎng)絡(luò)

    這篇文章主要介紹了使用Node.js配合Nginx實現(xiàn)高負(fù)載網(wǎng)絡(luò),Node的異步加上Nginx的反向代理在性能上實在是給力!需要的朋友可以參考下
    2015-06-06
  • 詳解nodejs的express如何自動生成項目框架

    詳解nodejs的express如何自動生成項目框架

    本篇文章主要介紹了nodejs的express如何自動生成項目框架,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • nodejs多版本管理總結(jié)

    nodejs多版本管理總結(jié)

    這篇文章主要介紹了nodejs多版本管理的相關(guān)知識點,以及實際操作方法和代碼,有需要的朋友參考下。
    2018-04-04
  • node中的session的具體使用

    node中的session的具體使用

    這篇文章主要介紹了node中的session的具體使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • npm?install報錯unable?to?resolve?dependency?tree的解決辦法

    npm?install報錯unable?to?resolve?dependency?tree的解決辦法

    在開發(fā)過程中經(jīng)常會使用npm安裝依賴包來加速開發(fā),但是在執(zhí)行npm install命令時,有時會遇到各種錯誤,下面這篇文章主要給大家介紹了關(guān)于npm?install報錯unable?to?resolve?dependency?tree的解決辦法,需要的朋友可以參考下
    2023-05-05

最新評論