首頁  >  文章  >  web前端  >  Node.js中的網路通訊模組實作方法詳解

Node.js中的網路通訊模組實作方法詳解

巴扎黑
巴扎黑原創
2017-08-16 11:54:381592瀏覽
前言
想必我們在用Node.js用的最多的應該是創建http服務,所以對於每個Web開發工程師而言,Node.js的網絡相關模組學習是必必不可少。
Node.js的網路模組架構
在Node.js的模組裡面,與網路相關的模組有Net、DNS、HTTP、TLS/SSL、HTTPS、UDP/Datagram,除此之外,還有v8底層相關的網路模組有tcp_wrap.cc、udp_wrap.cc、pipe_wrap.cc、stream_wrap.cc等等,在Javascript層以及C++層之間透過process.binding進行橋接相互通訊。
#Node.js中的網路通訊模組實作方法詳解

Net模組
Net模組提供了一些用於底層的網路通訊接口,包括建立伺服器以及客戶端,其中HTTP模組也是基於Net模型的上層封裝,在Net模組裡面主要提供net.Server以及net.Socket
建立TCP服務端
建立一個TCP伺服器,可以透過使用建構子new net.Server或使用工廠方法net.createServer,這兩個方法都會傳回一個net.Server類,可接收兩個可選參數。
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;});// 执行后:server run at { address: '::', family: 'IPv6', port: 56200 }

在listen監聽的時候沒有指定端口的話會自動隨意監聽一個端口,創建完成一個TCP伺服器後,使用tenlent 0.0.0.0 56200,鏈接後可與伺服器進行數據通信。透過createServer實例化一個服務後,服務會去監聽客戶端請求,與客戶端建立了連結之後會在回呼裡面拋出建鏈的net.Socket物件。
建立TCP客戶端
建立一個TCP客戶端連結可以使用建構子new net.Socket或其工廠方法net.createConnection,建立成功後都會傳回一個net.Socket實例。
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是啥這裡就不做詳細的闡述了,下面主要了解下net.Socket這個構造體主要有提供一些什麼方法、監聽事件的使用。
相關事件
connect : 當客戶端與服務端成功建立連結之後觸發,如果連結不上伺服器直接拋出error事件錯誤然後退出node進程。
data : 當客戶端收到伺服器傳送過來的資料或是客戶端傳送給伺服器的資料的時候觸發回呼。
end : 當另外一側發送FIN包斷開的時候觸發,預設情況下面(allowHalfOpen == false)socket會自我銷毀(如果寫入待處理隊列裡面還沒正式響應回包),但是我們可以設定allowHalfOpen參數為true,這樣可以繼續往該socket裡面寫數據,但是我們需要自己去呼叫end 方法去消耗這個socket,不然可能會造成句柄洩漏。
close : 連結斷開的時候觸發,但是如果在傳輸的過程中有錯誤的話這裡會在回調函數裡面拋出 error。
timeout : 當socket逾時空閒的時候觸發,如果要在佇列裡面銷毀需要手動去調close方法。
lookup : 網域解析完成的時候觸發。
drain : 寫完快取的時候觸發,可使用在上傳大小限制中。
相關方法
write() : 服務端傳送資料或客戶端傳送資料到服務端。
address() : 取得服務綁定的socket的IP位址,回傳物件有三個屬性,分別為連接埠、host以
及IPvX版本。
end() : 半關閉socket,會發送一個FIN包,伺服器仍然可能發送一些數據,也可以這樣調用socket.end(data,encoding)。
pause() : 暫停讀取數據,可用作資料上傳限制。
resume() : 繼續資料讀取。
setEncoding() : 設定資料流的取得格式。
setKeepAlive() : 允許/禁止keep-alive功能。
setNoDelay() : 禁止Nagele演算法,TCP連結預設使用Nagle演算法,它們在發送之前資料會被快取。這是為true的話在每次socket.write()的時候會立即發送數據,預設為true。
setTimeout() : 當一個空閒的socket在多少秒後不活躍會被接受到timeout事件,但是該socket不會停止銷毀,需要手動調用end()或者destroy()。表示禁止空閒超時。
相關屬性
bufferSize : 目前快取的等待被傳送的字串的數量。
bytesRead : 收到的位元組的數量。
bytesWritten : 發送的位元組的數量
destroyed : 標識連結是否已經被破壞,一旦被破環,就不用使用該連結來傳輸資料。
localAddress : 遠端客戶端連結本機位址的host。如果我們監聽服務的host是0.0.0.0,而客戶端連結的是'192.168.1.1',最後的值是後者。
localPort : 本地的連接埠。
remoteAddress : 客戶端IP,如果socket已經是destryed的話,該值為undefined。
remoteFamily : 用戶端是IPvX
回包異常處理
伺服器從客戶端接受到需要處理的資料後進入處理環節,再業務邏輯處理完成之前如果socket以外斷開的話,待伺服器再給客戶端回報的時候會直接回應error事件並報錯Error : This socket has benn ended by the other part,所以在回報之前服務端需要先判斷該socket是否被銷毀,如果沒有被銷毀則回包,如果已經斷開則銷毀:
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;});

限制客戶端資料大小
对请求大小限制是服务安全里面比不可少的一个环节,服务端不能无限大小的去接受客户端发送过来的所有数据,而限制大小就是第一道门槛。
var net = require('net');var MAX_REQUEST_BYTES = 2 * 1024 * 1024; // 2Mvar 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;});

以上是Node.js中的網路通訊模組實作方法詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn