前言
想必我們在用Node.js用的最多的應(yīng)該是創(chuàng)建http服務(wù),所以對于每個(gè)Web開發(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++層之間通過process.binding進(jìn)行橋接相互通信。

Net模塊
Net模塊提供了一些用于底層的網(wǎng)絡(luò)通信接口,包括創(chuàng)建服務(wù)器以及客戶端,其中HTTP模塊也是基于Net模型的上層封裝,在Net模塊里面主要提供net.Server以及net.Socket
創(chuàng)建TCP服務(wù)端
創(chuàng)建一個(gè)TCP服務(wù)器,可以通過使用構(gòu)造函數(shù)new net.Server或者使用工廠方法net.createServer,這兩個(gè)方法都會返回一個(gè)net.Server類,可接收兩個(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)聽的時(shí)候沒有指定端口的話會自動隨意監(jiān)聽一個(gè)端口,創(chuàng)建完成一個(gè)TCP服務(wù)器后,使用tenlent 0.0.0.0 56200,鏈接后可與服務(wù)器進(jìn)行數(shù)據(jù)通信。通過createServer實(shí)例化一個(gè)服務(wù)后,服務(wù)會去監(jiān)聽客戶端請求,與客戶端建立了鏈接之后會在回調(diào)里面拋出建鏈的net.Socket對象。
創(chuàng)建TCP客戶端
創(chuàng)建一個(gè)TCP客戶端鏈接可以使用構(gòu)造函數(shù)new net.Socket或者其工廠方法net.createConnection,創(chuàng)建成功后都會返回一個(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)聽事件的使用。
相關(guān)事件
allowHalfOpen == false)socket會自我銷毀(如果寫入待處理隊(duì)列里面還沒正式響應(yīng)回包),但是我們可以設(shè)置allowHalfOpen參數(shù)為true,這樣可以繼續(xù)往該socket里面寫數(shù)據(jù),但是我們需要自己去調(diào)用 end 方法去消耗這個(gè)socket,不然可能會造成句柄泄漏。相關(guān)方法
相關(guān)屬性
undefined。回包異常處理
服務(wù)器從客戶端接受到需要處理的數(shù)據(jù)后進(jìn)入處理環(huán)節(jié),再業(yè)務(wù)邏輯處理完成之前如果socket以外斷開的話,待服務(wù)器再給客戶端回報(bào)的時(shí)候會直接響應(yīng)error事件并報(bào)錯(cuò)Error : This socket has benn ended by the other part,所以在回報(bào)之前服務(wù)端需要先判斷該socket是否被銷毀,如果沒有被銷毀則回包,如果已經(jīng)斷開則銷毀:
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;});限制客戶端數(shù)據(jù)大小
對請求大小限制是服務(wù)安全里面比不可少的一個(gè)環(huán)節(jié),服務(wù)端不能無限大小的去接受客戶端發(fā)送過來的所有數(shù)據(jù),而限制大小就是第一道門檻。
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;});以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。
新聞熱點(diǎn)
疑難解答