1. 程式人生 > >node.js中net網絡模塊TCP服務端與客戶端的使用

node.js中net網絡模塊TCP服務端與客戶端的使用

pip sre tty 連接超時 .get 一個 調用 require putty

node.js中net模塊為我們提供了TCP服務器和客戶端通信的各種接口。

一、創建服務器並監聽端口

const net = require(‘net‘);

//創建一個tcp服務
//參數一表示創建服務的一些配置
//參數二表示 事件 ‘connection‘ 監聽回調函數
let server = net.createServer({
    //表示是否允許一個半開的TCP連接,默認為false
    allowHalfOpen: false,
    //一旦來了連接,是否暫停套接字,默認為false
    pauseOnConnect: false
});

server.listen(6666);

//一個新的連接建立時觸發 ‘connection‘ 事件
server.on(‘connection‘, function (socket) {
    //註意這裏的socket是一個流,既可以讀,也可以寫
    //當我們監聽 ‘data‘ 事件後,系統就會不斷的從流中讀取數據
    socket.on(‘data‘, function (data) {
        console.log(‘服務器接收到 : ‘, data.toString());
    });
});

//服務調用 server.listen() 監聽後就會觸發該事件
server.on(‘listening‘, function () {
    // address() 方法返回服務器地址信息對象
    let addr = server.address();
    console.log(`服務器監聽 : ${addr.port} 端口`);
});

//服務關閉時觸發,如果還有連接存在,則直到所有連接結束才會觸發該事件
server.on(‘close‘, function () {
    console.log(‘服務關閉‘);
});

//出現錯誤時觸發
server.on(‘error‘, function (err) {
    console.log(err);
});

windows下可以通過telnet 或 xshell,putty等工具連接上該服務,進行交互。

我們可以通過 getConnections() 實時獲取當前服務器的連接數。

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

//一個新的連接建立時觸發 ‘connection‘ 事件
server.on(‘connection‘, function (socket) {

    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    socket.on(‘data‘, function (data) {
        console.log(‘服務器接收到 : ‘, data.toString());
    });
});

我們可以手動的設置服務器的最大連接數,如果超過該連接數,則會拒絕連接。

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);

    //設置最大連接數為3,當有第4個連接請求時,連接會拒絕。
    server.maxConnections = 3;
});

//一個新的連接建立時觸發 ‘connection‘ 事件
server.on(‘connection‘, function (socket) {

    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    socket.on(‘data‘, function (data) {
        console.log(‘服務器接收到 : ‘, data.toString());
    });
});

我們也可以使用 close() 手動的拒絕所有連接請求,當已連接的客戶端都關閉後,則服務器會自動關閉,並觸發 ‘close‘ 事件。

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

//一個新的連接建立時觸發 ‘connection‘ 事件
server.on(‘connection‘, function (socket) {
    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    socket.on(‘data‘, function (data) {
        console.log(‘服務器接收到 : ‘, data.toString());
    });
});

server.on(‘close‘, function () {
    console.log(‘服務器被關閉‘);
});

//5秒後手動關閉服務器,拒絕所有連接請求,已有連接全部關閉後,觸發 ‘close‘ 事件
setTimeout(function () {
    server.close();
}, 5000);

調用 unref() 後,則當所有客戶端連接關閉後,將關閉服務器。ref() 功能與 unref() 相反。

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

//一個新的連接建立時觸發 ‘connection‘ 事件
server.on(‘connection‘, function (socket) {
    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    socket.on(‘data‘, function (data) {
        console.log(‘服務器接收到 : ‘, data.toString());
    });

    socket.on(‘close‘, function () {
        console.log(‘客戶端關閉‘);

        //調用unref()後,當所有客戶端連接都關閉後,將關閉服務器
        server.unref();
    });
});

server.on(‘close‘, function () {
    console.log(‘服務器關閉‘);
});

  

二、net.Socket是一個socket端口對象,是一個全雙工的可讀可寫流

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

server.on(‘connection‘, function (socket) {
    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    console.log(‘客戶端信息 : ‘, socket.address());

    //接收到數據時觸發
    socket.on(‘data‘, function (data) {
        //我們可以從流中讀取數據
        console.log(‘服務器接收到 : ‘, data.toString());
        console.log(‘累計接收的數據大小 : ‘, socket.bytesRead);
        console.log(‘累計發送的數據大小 : ‘, socket.bytesWritten);

        //也可以向流中寫入數據
        let flag = socket.write(`服務器向你發送 : ${data.toString()} \r\n`);
        console.log(‘flag : ‘, flag);
        console.log(‘當前已緩沖並等待寫入流中的字節數 : ‘, socket.bufferSize);
    });

    //連接關閉時觸發
    socket.on(‘end‘, function () {
        console.log(‘客戶端關閉‘);
    });

    //連接完全關閉時觸發
    socket.on(‘close‘, function () {
        console.log(‘客戶端完全關閉‘);
    });

    //發生錯誤時觸發
    socket.on(‘error‘, function (err) {
        console.log(err);
    });
});

我們可以通過 puase() 和 resume() 方法暫停讀寫數據。

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

server.on(‘connection‘, function (socket) {
    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    //接收到數據時觸發
    socket.on(‘data‘, function (data) {
        console.log(‘接收到的數據 : ‘, data.toString());

        setTimeout(function () {
            //3秒後暫停讀取數據
            socket.pause();
        }, 3000);

        setTimeout(function () {
            //6秒後恢復讀取數據
            socket.resume();
        }, 6000);
    });
});

net.Socket對象是一個流,既然是流,那麽我們可以通過 pipe() 方法建一個到文件的可寫流,把從客戶端接收的數據寫入到一個文件中。

const net = require(‘net‘);
const fs = require(‘fs‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

let ws = fs.createWriteStream(‘./1.txt‘);

server.on(‘connection‘, function (socket) {
    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    //接收到數據時觸發
    socket.on(‘data‘, function (data) {
        console.log(‘接收到的數據 : ‘, data.toString());
    });

    //註意這裏的第二個參數,設為 false。
    //每當有一個新的連接時,就會創建一個新的 socket 對象。
    //不然當第一個socket對象結束操作或關閉時,會自動關閉 ws 可寫流。
    //後續的socket對象將無法往 ws 裏寫入數據。
    socket.pipe(ws, {end: false});

    socket.on(‘end‘, function () {
        console.log(‘客戶端關閉‘);
        socket.unpipe(ws);
    });
});

通過 setTimeout() 我們可以設置一個連接活動的超時時間,當一個連接超時時,將觸發 ‘timeout‘ 事件。

const net = require(‘net‘);

let server = net.createServer();
server.listen(6666, ‘0.0.0.0‘, function () {
    console.log(‘服務器監聽開始‘);
});

server.on(‘connection‘, function (socket) {
    //獲取當前服務器的連接數
    server.getConnections(function (error, count) {
        console.log(‘當前服務器的連接數 : ‘, count);
    });

    //接收到數據時觸發
    socket.on(‘data‘, function (data) {
        console.log(‘接收到的數據 : ‘, data.toString());
    });

    socket.setTimeout(3 * 1000);
    //連接超時後,並不會斷開,需手動調用 end() 或 destroy() 來斷開連接
    socket.on(‘timeout‘, function () {
        console.log(‘當前連接已超時‘);
    });
});

  

三、創建一個tcp客戶端

const net = require(‘net‘);

//創建一個tcp客戶端
let client = new net.Socket();
client.connect({
    host: ‘127.0.0.1‘,
    port: 6666
});

//客戶端與服務器建立連接觸發
client.on(‘connect‘, function () {
    client.write(‘你好服務器‘);
});

//客戶端接收數據觸發
client.on(‘data‘, function (data) {
    console.log(‘服務器發送的數據 : ‘, data.toString());
});

客戶端可以通過調用 end() 方法來主動關閉與服務端的連接。

const net = require(‘net‘);

//創建一個tcp客戶端
let client = new net.Socket();
client.connect({
    host: ‘127.0.0.1‘,
    port: 6666
});

//客戶端與服務器建立連接時觸發
client.on(‘connect‘, function () {
    //往服務端寫入數據
    client.write(‘你好服務器‘);
});

//客戶端接收數據時觸發
client.on(‘data‘, function (data) {
    console.log(‘服務器發送的數據 : ‘, data.toString());
});

setTimeout(function () {
    client.end();
}, 3000);

通過 setKeepAlive() 方法來禁用或啟用長連接功能,防止時間過短而斷開連接。setKeepAlive() 會發送一個空包,來保持通信。

const net = require(‘net‘);

//創建一個tcp客戶端
let client = new net.Socket();
client.connect({
    host: ‘127.0.0.1‘,
    port: 6666
});

//設置連接保持
client.setKeepAlive(true, 3000);

//客戶端與服務器建立連接觸發
client.on(‘connect‘, function () {
    client.write(‘你好服務器‘);
});

//客戶端接收數據觸發
client.on(‘data‘, function (data) {
    console.log(‘服務器發送的數據 : ‘, data.toString());
});

setTimeout(function () {
    client.end();
}, 3000);

  

node.js中net網絡模塊TCP服務端與客戶端的使用