最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js之網(wǎng)絡(luò)通訊模塊實(shí)現(xiàn)淺析

 更新時(shí)間:2017年04月01日 15:04:26   作者:C小K  
本篇文章主要介紹了Node.js之網(wǎng)絡(luò)通訊模塊實(shí)現(xiàn)淺析,具有一定的參考價(jià)值,有興趣的可以了解一下。

前言

想必我們?cè)谟肗ode.js用的最多的應(yīng)該是創(chuàng)建http服務(wù),所以對(duì)于每個(gè)Web開(kāi)發(fā)工程師而言,Node.js的網(wǎng)絡(luò)相關(guān)模塊學(xué)習(xí)是必不可少。

Node.js的網(wǎng)絡(luò)模塊架構(gòu)

在Node.js的模塊里面,與網(wǎng)絡(luò)相關(guān)的模塊有Net、DNS、HTTP、TLS/SSL、HTTPS、UDP/Datagram,除此之外,還有v8底層相關(guān)的網(wǎng)絡(luò)模塊有tcp_wrap.cc、udp_wrap.cc、pipe_wrap.cc、stream_wrap.cc等等,在Javascript層以及C++層之間通過(guò)process.binding進(jìn)行橋接相互通信。

Net模塊

Net模塊提供了一些用于底層的網(wǎng)絡(luò)通信接口,包括創(chuàng)建服務(wù)器以及客戶(hù)端,其中HTTP模塊也是基于Net模型的上層封裝,在Net模塊里面主要提供net.Server以及net.Socket

創(chuàng)建TCP服務(wù)端

創(chuàng)建一個(gè)TCP服務(wù)器,可以通過(guò)使用構(gòu)造函數(shù)new net.Server或者使用工廠方法net.createServer,這兩個(gè)方法都會(huì)返回一個(gè)net.Server類(lèi),可接收兩個(gè)可選參數(shù)。

var net = require('net');

var server = net.createServer(function(socket){

  socket
    .on('data',function(data){
      console.log('socket data',data.toString());
      socket.write( data.toString() );
    })
    .on('end',function(){
      console.log('socket end')
    })
    .on('error',function(error){
      console.log('socket error',error);
    });
});

server.listen(56200,function(){
  console.log('server run at ',server.address());
});

server.on('error',function(err){
  throw err;
});
// 執(zhí)行后:server run at { address: '::', family: 'IPv6', port: 56200 }

在listen監(jiān)聽(tīng)的時(shí)候沒(méi)有指定端口的話(huà)會(huì)自動(dòng)隨意監(jiān)聽(tīng)一個(gè)端口,創(chuàng)建完成一個(gè)TCP服務(wù)器后,使用tenlent 0.0.0.0 56200,鏈接后可與服務(wù)器進(jìn)行數(shù)據(jù)通信。通過(guò)createServer實(shí)例化一個(gè)服務(wù)后,服務(wù)會(huì)去監(jiān)聽(tīng)客戶(hù)端請(qǐng)求,與客戶(hù)端建立了鏈接之后會(huì)在回調(diào)里面拋出建鏈的net.Socket對(duì)象。

創(chuàng)建TCP客戶(hù)端

創(chuàng)建一個(gè)TCP客戶(hù)端鏈接可以使用構(gòu)造函數(shù)new net.Socket或者其工廠方法net.createConnection,創(chuàng)建成功后都會(huì)返回一個(gè)net.Socket實(shí)例。

var net = require('net');

var client = net.createConnection({port:56200,host:'localhost'});

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

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

client.on('error',function(error){
  throw error;
});

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

Socket

socket是啥這里就不做詳細(xì)的闡述了,下面主要了解下net.Socket這個(gè)構(gòu)造體主要有提供一些什么方法、監(jiān)聽(tīng)事件的使用。

相關(guān)事件

  1. connect : 當(dāng)客戶(hù)端與服務(wù)端成功建立鏈接之后觸發(fā),如果鏈接不上服務(wù)器直接拋出error事件錯(cuò)誤然后退出node進(jìn)程。
  2. data : 當(dāng)客戶(hù)端收到服務(wù)器傳送過(guò)來(lái)的數(shù)據(jù)或者是客戶(hù)端傳送給服務(wù)器的數(shù)據(jù)的時(shí)候觸發(fā)回調(diào)。
  3. end : 當(dāng)另外一側(cè)發(fā)送FIN包斷開(kāi)的時(shí)候觸發(fā),默認(rèn)情況下面 (allowHalfOpen == false)socket會(huì)自我銷(xiāo)毀(如果寫(xiě)入待處理隊(duì)列里面還沒(méi)正式響應(yīng)回包),但是我們可以設(shè)置allowHalfOpen參數(shù)為true,這樣可以繼續(xù)往該socket里面寫(xiě)數(shù)據(jù),但是我們需要自己去調(diào)用 end 方法去消耗這個(gè)socket,不然可能會(huì)造成句柄泄漏。
  4. close : 鏈接斷開(kāi)的時(shí)候觸發(fā),但是如果在傳輸?shù)倪^(guò)程中有錯(cuò)誤的話(huà)這里會(huì)在回調(diào)函數(shù)里面拋出 error。
  5. timeout : 當(dāng)socket超時(shí)空閑的時(shí)候觸發(fā),如果要在隊(duì)列里面銷(xiāo)毀需要手動(dòng)去調(diào)close方法。
  6. lookup : 域名解析完成的時(shí)候觸發(fā)。
  7. drain : 寫(xiě)完緩存的時(shí)候觸發(fā),可使用在上傳大小限制中。

相關(guān)方法

  1. write() : 服務(wù)端給客戶(hù)端發(fā)送數(shù)據(jù)或者是客戶(hù)端給服務(wù)端發(fā)送數(shù)據(jù)。
  2. address() : 獲取服務(wù)綁定的socket的IP地址,返回對(duì)象有三個(gè)屬性,分別為端口、host以
  3. 及IPvX版本。
  4. end() : 半關(guān)閉socket,會(huì)發(fā)送一個(gè)FIN包,服務(wù)器仍然可能發(fā)送一些數(shù)據(jù),也可以這樣調(diào)用socket.end(data,encoding)。
  5. pause() : 暫停讀取數(shù)據(jù),可以用作對(duì)數(shù)據(jù)上傳限制。
  6. resume() : 繼續(xù)數(shù)據(jù)讀取。
  7. setEncoding() : 設(shè)置數(shù)據(jù)流的獲取格式。
  8. setKeepAlive() : 允許/禁止keep-alive功能。
  9. setNoDelay() : 禁止Nagele算法,TCP鏈接默認(rèn)使用Nagle算法,它們?cè)诎l(fā)送之前數(shù)據(jù)會(huì)被緩存。這是為true的話(huà)在每次socket.write()的時(shí)候會(huì)立即發(fā)送數(shù)據(jù),默認(rèn)為true。
  10. setTimeout() : 當(dāng)一個(gè)空閑的socket在多少秒后不活躍會(huì)被接受到timeout事件,但是該socket不會(huì)停止銷(xiāo)毀,需要手動(dòng)調(diào)用end()或者destroy()。表示禁止空閑超時(shí)。

相關(guān)屬性

  1. bufferSize : 當(dāng)前緩存的等待被發(fā)送的字符串的數(shù)量。
  2. bytesRead : 收到的字節(jié)的數(shù)量。
  3. bytesWritten : 發(fā)送的字節(jié)的數(shù)量
  4. destroyed : 標(biāo)識(shí)鏈接是否已經(jīng)被破壞,一旦被破環(huán),就不用使用該鏈接來(lái)傳輸數(shù)據(jù)。
  5. localAddress : 遠(yuǎn)程客戶(hù)端鏈接本地地址的host。如果我們監(jiān)聽(tīng)服務(wù)的host是0.0.0.0,而客戶(hù)端鏈接的是'192.168.1.1',最后的值是后者。
  6. localPort : 本地的端口。
  7. remoteAddress : 客戶(hù)端IP,如果socket已經(jīng)是destryed的話(huà),該值為undefined。
  8. remoteFamily : 客戶(hù)端是IPvX

回包異常處理

服務(wù)器從客戶(hù)端接受到需要處理的數(shù)據(jù)后進(jìn)入處理環(huán)節(jié),再業(yè)務(wù)邏輯處理完成之前如果socket以外斷開(kāi)的話(huà),待服務(wù)器再給客戶(hù)端回報(bào)的時(shí)候會(huì)直接響應(yīng)error事件并報(bào)錯(cuò)Error : This socket has benn ended by the other part,所以在回報(bào)之前服務(wù)端需要先判斷該socket是否被銷(xiāo)毀,如果沒(méi)有被銷(xiāo)毀則回包,如果已經(jīng)斷開(kāi)則銷(xiāo)毀:

var net = require('net');
var biz = require('./biz');
var server = net.createServer(function(socket){

  socket
    .on('data',function(data){
      biz.do(data)
        .then(function(){
          if( !socket.destroyed ) {
            socket.write( data.toString() );
          } else {
            // do some report
            socket.destry();
          }
        })
        .catch(function(){
          !socket.destroyed && socket.end('server handler error');
        });
      
    })
    .on('end',function(){
      console.log('socket end')
    })
    .on('error',function(error){
      console.log('socket error',error);
    });
});

server.listen(56200,function(){
  console.log('server run at ',server.address());
});

server.on('error',function(err){
  throw err;
});

限制客戶(hù)端數(shù)據(jù)大小

對(duì)請(qǐng)求大小限制是服務(wù)安全里面比不可少的一個(gè)環(huán)節(jié),服務(wù)端不能無(wú)限大小的去接受客戶(hù)端發(fā)送過(guò)來(lái)的所有數(shù)據(jù),而限制大小就是第一道門(mén)檻。

var net = require('net');
var MAX_REQUEST_BYTES = 2 * 1024 * 1024; // 2M
var server = net.createServer(function(socket){

  socket
    .on('data',function(data){
      
      if(data.bytesRead > MAX_REQUEST_BYTES) {
        socket.pause();
        socket.end('data is too big, forbidden');
        // do some report
      }
    })
    .on('end',function(){
      console.log('socket end')
    })
    .on('error',function(error){
      console.log('socket error',error);
    });
});

server.listen(56200,function(){
  console.log('server run at ',server.address());
});

server.on('error',function(err){
  throw err;
});

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node.js+jQuery實(shí)現(xiàn)用戶(hù)登錄注冊(cè)AJAX交互

    node.js+jQuery實(shí)現(xiàn)用戶(hù)登錄注冊(cè)AJAX交互

    本篇文章主要介紹了用Node.js當(dāng)作后臺(tái)、jQuery寫(xiě)前臺(tái)AJAX代碼實(shí)現(xiàn)用戶(hù)登錄和注冊(cè)的功能的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-04-04
  • node前端模板引擎Jade之標(biāo)簽的基本寫(xiě)法

    node前端模板引擎Jade之標(biāo)簽的基本寫(xiě)法

    這篇文章主要介紹了node前端模板引擎Jade之標(biāo)簽的基本寫(xiě)法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 詳解基于node.js的腳手架工具開(kāi)發(fā)經(jīng)歷

    詳解基于node.js的腳手架工具開(kāi)發(fā)經(jīng)歷

    這篇文章主要介紹了詳解基于node.js的腳手架工具開(kāi)發(fā)經(jīng)歷,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Node.js中下包速度慢問(wèn)題解決方法分析

    Node.js中下包速度慢問(wèn)題解決方法分析

    這篇文章主要介紹了Node.js中下包速度慢問(wèn)題解決方法,分析了npm切換鏡像源以及nrm工具鏡像源管理相關(guān)使用技巧,需要的朋友可以參考下
    2023-04-04
  • npm與nrm兩種方式查看源和切換鏡像詳解

    npm與nrm兩種方式查看源和切換鏡像詳解

    nrm(npm registry manager )是npm的鏡像源管理工具,它可以快速在讓你在本地源之間切換,下面這篇文章主要給大家介紹了關(guān)于npm與nrm兩種方式查看源和切換鏡像的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • node下使用UglifyJS壓縮合并JS文件的方法

    node下使用UglifyJS壓縮合并JS文件的方法

    下面小編就為大家分享一篇node下使用UglifyJS壓縮合并JS文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • node.js版本管理工具n無(wú)效的原理和解決方法

    node.js版本管理工具n無(wú)效的原理和解決方法

    大家都知道在Centos中一般需要根據(jù)項(xiàng)目的環(huán)境安裝指定版本的Node, 而現(xiàn)有的yum源版本一般不夠全面也不一定找的到所需要的指定版本, 此時(shí)就必須自行下載Node源碼進(jìn)行編譯安裝了,如果你在使用node.js版本管理工具n的時(shí)候發(fā)現(xiàn)工具無(wú)效,下面就來(lái)看看這篇文章的解決方法吧。
    2016-11-11
  • 在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線(xiàn)推送的方法

    在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線(xiàn)推送的方法

    這篇文章主要介紹了在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線(xiàn)推送的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 基于NodeJS+MongoDB+AngularJS+Bootstrap開(kāi)發(fā)書(shū)店案例分析

    基于NodeJS+MongoDB+AngularJS+Bootstrap開(kāi)發(fā)書(shū)店案例分析

    這章的目的是為了把前面所學(xué)習(xí)的內(nèi)容整合一下,這個(gè)示例完成一個(gè)簡(jiǎn)單圖書(shū)管理模塊,因?yàn)橹虚g需要使用到Bootstrap這里先介紹Bootstrap
    2017-01-01
  • nodejs讀取本地mp3和mp4等媒體文件并播放的案例

    nodejs讀取本地mp3和mp4等媒體文件并播放的案例

    fs模塊是nodejs官方提供用來(lái)操作文件的模塊,下面這篇文章主要給大家介紹了關(guān)于nodejs讀取本地mp3和mp4等媒體文件并播放的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09

最新評(píng)論

辛集市| 洛浦县| 克拉玛依市| 博湖县| 高唐县| 林周县| 朝阳市| 旬阳县| 广平县| 静海县| 莆田市| 汶川县| 平利县| 花垣县| 汶上县| 雷州市| 醴陵市| 永定县| 瑞金市| 乌审旗| 桂东县| 四平市| 汾西县| 无棣县| 上蔡县| 上杭县| 佛山市| 冕宁县| 宜兰市| 娄烦县| 绍兴县| 阜城县| 集安市| 沙坪坝区| 西华县| 郓城县| 房山区| 伊通| 马山县| 买车| 胶州市|