深刻淺出Node.js學習筆記(七)

網絡編程

利用Node能夠十分方便的搭建網絡服務器。算法

Node提供了net、dgram、http、https等4個模塊,分別用於處理TCP、UDP、HTTP、HTTPS,適用於服務器端和客戶端。編程

1. 構建TCP服務

TCP服務在網絡應用中十分常見,大多數的應用都是基於TCP搭建而成的。瀏覽器

1.1 TCP

TCP全名爲傳輸控制協議,在OSI模型(物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層)中屬於傳輸層協議。安全

TCP是面向鏈接的協議,其顯著的特徵是傳輸以前須要3次握手造成會話。bash

只有會話造成後,服務器端和客戶端之間才能相互發送數據。在建立會話的過程當中,服務器端和客戶端分別提供一個套接字,這兩個套接字共同造成一個鏈接。服務器端和客戶端則經過套接字實現二者之間的操做。服務器

1.2 建立TCP服務器端

經過net.createServer(listener)便可建立一個TCP服務器,listener是鏈接事件connection的偵聽器。網絡

能夠利用Telnet工具做爲客戶端對建立的服務器進行會話交流。併發

1.3 TCP服務的事件

TCP服務的事件分爲服務器事件和鏈接事件。socket

  1. 服務器事件高併發

    對於經過net.createServer()建立的服務器而言,它是一個EventEmitter實例,自定義事件有:

    • listening
    • connection
    • close
    • error
  2. 鏈接事件

    服務器能夠同時與多個客戶端保持鏈接,對於每一個鏈接而言是典型的可寫可讀Stream對象。Stream對象能夠用於服務器端和客戶端之間的通訊,既能夠經過data事件從一端讀取另外一端發來的數據,也能夠經過write()方法從一端向另外一端發送數據。自定義事件:

    • data
    • end
    • connect
    • drain
    • error
    • close
    • timeout

    TCP套接字是可寫可讀的Stream對象,能夠利用pipe()方法巧妙地實現管道操做。

    TCP針對網絡中的小數據也有必定的優化策略:Nagle算法。

    Nagle算法:

    要求緩衝區的數據達到必定數量或者必定時間後纔將其發出,因此小數據包會被Nagle算法合併,所以來優化網絡。雖然網絡帶寬被有效地使用,可是數據有可能被延遲發送。

2. 構建UDP服務

UDP全稱爲用戶數據包協議,與TCP同樣屬於網絡傳輸層。UDP和TCP最大的不一樣是UDP不是面向鏈接的。

2.1建立UDP套接字

建立UDP套接字十分的簡單,UDP套接字一旦被建立,既能夠做爲客戶端發送數據,也能夠做爲服務器端接收數據。

var dgram = rerquire('dgram');
var socket = dgram.createSocket("udp4");
複製代碼

2.2 建立UDP服務器端

想要UDP套接字接收網絡信息,只要調用dgram.bind(port,[address])方法對網卡和端口進行綁定便可。

建立UDP服務器端示例:

var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
    console.log("server got: " + msg + " from " +
        rinfo.address + ":" + rinfo.port);
});
server.on("listening", function () {
    var address = server.address();
    console.log("server listening " +
        address.address + ":" + address.port);
});
server.bind(41234);
複製代碼

2.3 建立UDP客戶端

建立UDP客戶端示例:

var dgram = require('dgram');
var message = new Buffer("深刻淺出Node.js");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost", function (err, bytes) {
    client.close();
});
複製代碼

2.4 UDP套接字事件

UDP套接字只是一個EventEmitter的實例。自定義事件:

  • message
  • listening
  • close
  • error

3. 構建HTTP服務

Node提供了基本的http和https模塊用於HTTP和HTTPS的封裝。

HTTP服務器的實現:

var http = require('http');
http.createServer(function (req, res) {
	res.writeHead(200, {'Content-Type': 'text/plain'});
	res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
複製代碼

3.1 HTTP

  1. 初始HTTP

    HTTP的全稱是超文本傳輸協議(HyperText Transfer Protocol)。

    HTTP構建在TCP之上,屬於應用層協議。

  2. HTTP報文

    HTTP是基於請求響應式的,以一問一答的方式實現服務。

    HTTP服務只作兩件事:處理HTTP請求和發送HTTP響應。

    不管是HTTP請求報文仍是HTTP響應報文,報文內容都包含兩個部分:報文頭和報文體。

3.2 HTTP模塊

Node的http模塊包含對HTTP處理的封裝。

在Node中,HTPP服務繼承自TCP服務器(net模塊),它可以與多個客戶端保持鏈接,因爲其採用事件驅動的形式,並非爲每個鏈接建立額外的線程或進程,保持很低的內存佔用,因此可以實現高併發。

HTTP服務和TCP服務模型的區別在於,在開啓keepalive後,一個TCP會話能夠用於屢次請求和響應。TCP服務以connection爲單元進行服務,HTTP服務以request爲單位進行服務。

http模塊將鏈接所用套接字的讀寫抽象爲ServerRequest和ServerResponse對象,分別對應請求和響應操做。

  1. HTTP請求

    對於TCP鏈接的讀操做,http模塊將其封裝爲ServerRequest對象。

  2. HTTP響應

    HTTP響應對象封裝了對底層鏈接的寫操做,能夠將其看作一個可寫的流對象。

    響應結束後,HTTP服務器可能會將當前的鏈接用於下一個請求,或者關閉鏈接。

  3. HTTP服務的事件

    HTTP服務也是個EventEmitter實例:

    • connection事件
    • request事件
    • close事件
    • checkContinue事件
    • connect事件
    • upgrade事件
    • clientError事件

3.3 HTTP客戶端

HTTP客戶端是服務器服務模型的另外一部分,處在HTTP的另外一端,在整個報文的參與中,報文頭和報文體由它產生。

  1. HTTP響應

    HTTP客戶端在CLientRequest對象中,它的事件叫作response。

  2. HTTP代理

    http提供的ClientRequest對象是基於TCP層實現的,在keepalive的狀況下,一個底層會話鏈接能夠屢次用於請求。爲了重用TCP鏈接,http模塊包含一個默認的客戶端代理對象http。globalAgent.t它對每一個服務器端(host+port)建立的鏈接進行了管理,默認狀況下,經過ClientRequest對象對同一個服務器發起的HTTP請求最多能夠建立5個鏈接。它的實質是一個鏈接池。

    調用HTTP客戶端同時對一個服務器發起10次請求時,其實質只有5個請求處於併發狀態,後續的請求完成服務後才真正發出。這與瀏覽器對同一個域名有下載鏈接數的限制是相同的行爲。

  3. HTTP客戶端事件

    • response
    • socket
    • upgrade
    • continue

4. 構建WebSocket服務

WebSocket與Node之間的配合堪稱完美的理由:

  • WebSocket客戶端基於時間的編程模型與Node自定義事件相差無幾;
  • WebSocket實現了客戶端和服務器端之間的長鏈接,而Node事件驅動的方式十分擅長於大量的客戶端保持高併發鏈接;

WebSocket與傳統HTTP的好處:

  • 客戶端與服務器端只創建一個TCP鏈接,可使用更少的鏈接;
  • WebSocket服務器端能夠推送數據到客戶端,這遠比HTTP請求響應模式更加靈活、更加高效;
  • 有更輕量級的協議頭,減小數據傳送量;

使用WebSocket,網頁客戶端只須要一個TCP鏈接便可完成雙向通訊,在服務器與客戶端頻繁通訊時,無須頻繁斷開鏈接和重發請求。

WebSocket與HTTP的區別:

相比HTTP,WebSocket更接近於傳輸層協議,並無在HTTP的基礎上模擬服務器端的推送,而是在TCP上定義的獨立的協議。

WebSocket協議主要分爲兩個部分:握手和數據傳輸。

4.1 WebSocket握手

一旦WebSocket握手成功,服務器端與客戶端將會呈現對等的效果,都能接收和發送消息。

4.2 WebSocket數據傳輸

在握手順利完成後,當前鏈接再也不進行HTTP的交互,而是開始WebSocket的數據幀協議。實現客戶端與服務器端的數據交換。

5. 網絡服務與安全

5.1 TLS/SSL

  1. 密鑰

    TLS/SSL是一個公鑰/私鑰的結構,它是一個非對稱的結構,每一個服務器端和客戶端都有本身的公私鑰。

    公鑰用來加密要傳輸的數據,私鑰用來解密接收到的數據。

    公鑰和私鑰是配對的,經過公鑰加密的數據,只有經過私鑰才能解密,因此在創建安全傳輸以前,客戶端和服務器端之間須要互換公鑰。客戶端發送數據時要經過服務器端的公鑰進行加密,服務器端發送數據時則須要客戶端的公鑰進行加密。

    公私鑰的非對稱加密雖好,可是網絡中依然可能存在竊聽的狀況,典型的例子就是中間人攻擊。

    客戶端和服務器端在交換公鑰的過程當中,中間人對客戶端扮演服務器端的角色,對服務器端扮演客戶端的角色,所以客戶端和服務器端幾乎感覺不到中間人的攻擊。

    爲了解決中間人攻擊,數據傳輸過程當中還須要對獲得的公鑰進行認證,以確認獲得的公鑰是出自目標服務器。

  2. 數字證書

    爲了確保數據的安全,引入第三方:CA(Certificate Authority,數字證書認證中心)。

    CA的做用是爲站點頒發證書,且這個證書中具備CA經過本身的公鑰和私鑰實現的簽名。

    爲了獲得簽名證書,服務器端須要經過本身的私鑰生成CSR(Certificate Signing Request,證書籤名請求)文件。CA機構將經過這個文件頒發屬於該服務器的簽名證書,只要經過CA機構就能驗證證書是否合法。

5.2 TLS服務

  1. 建立服務器端
  2. TLS客戶端

與普通的TCP服務器端和客戶端相比,TLS的服務器端和客戶端僅僅只在證書的配置上有差異,其他部分基本相同。

5.3 HTTPS服務

HTTPS服務就是工做在TLS/SSL上的HTTP。

  1. 準備證書
  2. 建立HTTPS服務
  3. HTTP客戶端
相關文章
相關標籤/搜索