Node入門教程(11)第九章:Node 的網(wǎng)絡(luò)模塊

net網(wǎng)絡(luò)模塊

net模塊是node對TCP或者IPC開發(fā)的封裝,包括了客戶端和服務(wù)器端相關(guān)API。對于閱讀本文,請您有一定的網(wǎng)絡(luò)編程的基礎(chǔ)。
您需要已經(jīng)了解了:

  • ip協(xié)議,會(huì)配置ip地址
  • 了解dns解析過程,了解dns的概念
  • 了解基本的TCP的協(xié)議的
  • 了解Socket的編程相關(guān)概念
  • 了解node的事件處理、流、文件處理等
  • 了解HTTP協(xié)議

本文,僅對部分API和TCP開發(fā)做一些簡單介紹。

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

net.Server 類用于創(chuàng)建TCP的server,而且繼承了EventEmitter。通過net.createServer([options][, connectionListener])方法創(chuàng)建此類型實(shí)例。

const net = require('net');

// 創(chuàng)建服務(wù)器端的
const server = net.createServer();

// 監(jiān)聽異常錯(cuò)誤事件
server.on('error', err => {
  // throw err;
  console.log(err);
});

// 監(jiān)聽客戶端的連接事件,客戶端連接上后,會(huì)自動(dòng)執(zhí)行回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)就是指向客戶端的socket
server.on('connection', clientSocket => {
  console.log('客戶端:%s', clientSocket.remoteAddress);

  // 監(jiān)聽此客戶端的end事件。
  clientSocket.on('end', () => {
    console.log('client disconnected');
  });

  // 監(jiān)聽此客戶端發(fā)送數(shù)據(jù)的事件。
  clientSocket.on('data', data => {
    console.log('收到數(shù)據(jù):%s', data);
  });

  // 向客戶端發(fā)送數(shù)據(jù)
  clientSocket.write('Hi, aicoder.com ');

  // 2s后讓客戶端退出
  setTimeout(() => {
    // 通知客戶端退出,并發(fā)送數(shù)據(jù)。
    clientSocket.end('bye!');
  }, 2000);
});

// 服務(wù)器開始監(jiān)聽60003端口(端口:0-65535之間的一個(gè)值)
server.listen(60003, () => {
  console.log('opened server on', server.address());
});

// 以下為關(guān)閉監(jiān)聽的實(shí)例
// setTimeout(() => {
//   console.log('服務(wù)器端退出?。。?);
//   server.close();
// }, 5000);

net.Server 是對服務(wù)器端的Socket的封裝,可以監(jiān)聽close事件、error事件、connection 事件、listening 事件。還可以通過close()方法關(guān)閉服務(wù)的監(jiān)聽。其他用法參考官網(wǎng)文檔

net.Socket 類是對客戶端Socket的封裝,可以監(jiān)聽 close 事件、 connect 事件 、data 事件、drain 事件、end 事件、error 事件、lookup 事件、timeout 事件??捎玫姆椒òǎ?code>write()發(fā)送數(shù)據(jù)、edn()結(jié)束連接等。其中可以同data事件來處理服務(wù)器端的數(shù)據(jù)。

創(chuàng)建TCP的客戶端

net.createConnection()方法可以實(shí)現(xiàn)連接服務(wù)器端,并生成一個(gè)net.Socket 類實(shí)例,跟服務(wù)器端進(jìn)行交互就是靠此實(shí)例。

const net = require('net');

// 創(chuàng)建連接到服務(wù)器的客戶端
let client = net.createConnection('60003', '127.0.0.1', () => {
  client.write('Hi, client, for aicoder.com');
  console.log('連接上服務(wù)器端!');
});

client.on('error', err => {
  console.log(err);
});

client.on('end', () => {
  console.log('結(jié)束連接!');
});

client.on('close', () => {
  console.log('退出');
});

client.on('data', data => {
  console.log('收到數(shù)據(jù): %s', data);
});

通過Socket上傳文件的例子

const net = require('net');
const path = require('path');
const fs = require('fs');

// 創(chuàng)建服務(wù)器端的
const server = net.createServer();

// 監(jiān)聽異常錯(cuò)誤事件
server.on('error', err => {
  console.log(err);
});

// 監(jiān)聽客戶端的連接事件,客戶端連接上后,會(huì)自動(dòng)執(zhí)行回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)就是指向客戶端的socket
server.on('connection', clientSocket => {
  console.log('客戶端:%s', clientSocket.remoteAddress);

  // 監(jiān)聽此客戶端的end事件。
  clientSocket.on('end', () => {
    console.log('client disconnected');
  });

  // 監(jiān)聽此客戶端發(fā)送數(shù)據(jù)的事件。
  clientSocket.on('data', data => {
    console.log('收到數(shù)據(jù):%s', data);
    let fileName = path.join(__dirname, 'b.html');
    let ws = fs.createWriteStream(fileName);
    ws.write(data, 'utf8');
  });

  // 向客戶端發(fā)送數(shù)據(jù)
  clientSocket.write('Hi, aicoder.com ');
});

// 服務(wù)器開始監(jiān)聽60003端口(端口:0-65535之間的一個(gè)值)
server.listen(60003, () => {
  console.log('opened server on', server.address());
});

// 以下是客戶端代碼
const client = net.createConnection(60003, '127.0.0.1', () => {
  console.log('連接上服務(wù)器端!');
  let fileName = path.join(__dirname, 'a.html');
  let rs = fs.createReadStream(fileName, { encoding: 'utf8' });
  // socket本身是可讀可寫流,所以可以直接用管道。
  rs.pipe(client);
});

模擬一個(gè)WEB服務(wù)器軟件

如果您已經(jīng)了解了HTTP協(xié)議的話,而且已經(jīng)掌握如何做TCP的發(fā)送數(shù)據(jù)和接受處理數(shù)據(jù),再有您稍微掌握一點(diǎn)字符串處理的技巧,那么您就很容易做一個(gè)簡單的靜態(tài)web服務(wù)器出啦。當(dāng)然這里是說用底層的API,不是用http模塊。

限于篇幅,在此不再贅述,請直接看我的github源碼,僅僅是demo,不要用于生產(chǎn)環(huán)境中。

總結(jié)

node中對socket的封裝,還是比較像node的開發(fā)風(fēng)格的,可能跟其他平臺(tái)的socket編程的風(fēng)格不一致,但是原理和開發(fā)方式都是一樣的。這里僅僅是簡單介紹一下Node下面網(wǎng)絡(luò)編程的基本方法,細(xì)節(jié)請參考官網(wǎng)文檔。


老馬免費(fèi)視頻教程

返回教程列表首頁

github地址:https://github.com/malun666/aicoder_node

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò)編程 網(wǎng)絡(luò)編程對于很多的初學(xué)者來說,都是很向往的一種編程技能,但是很多的初學(xué)者卻因?yàn)楹荛L一段時(shí)間無法進(jìn)入網(wǎng)絡(luò)編...
    程序員歐陽閱讀 2,105評論 1 37
  • 計(jì)算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(gè)(或多個(gè))設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸。 按照計(jì)算機(jī)網(wǎng)絡(luò)的定義,通過一定...
    蛋炒飯_By閱讀 1,369評論 0 10
  • Socket編程 1基礎(chǔ)知識(shí) 協(xié)議 端口號(hào)(辨別不同應(yīng)用) TCP/IP協(xié)議 是目前世界上應(yīng)用最廣泛的協(xié)議是以TC...
    __豆約翰__閱讀 1,191評論 0 3
  • 遇到什么問題? 我們說,類是對象的抽象,是對象的模板,對象是類的實(shí)例.我們現(xiàn)在需要使用一種方式來表示整個(gè)事物共同都...
    buzhidao_閱讀 468評論 0 1
  • 請求是非暴力溝通的第四個(gè)步驟。 要提出具體要求,清楚告訴對方,我希望他們做些什么。如果只告訴對方不做什么,對方很容...
    5200一口閱讀 430評論 0 1

友情鏈接更多精彩內(nèi)容