[Node.js] socket 實作1:伺服器端與客戶端的監聽通訊(TCP)

Node.js 提供了 net 模組來支援 TCP 協定應用;另有 UDP 模組來支援 UDP 協定應用。
TCP 和 UDP 協定是屬於 ISO 七層中的傳輸層協定。其中 TCP 為 IP 環境下的資料,提供可靠性傳輸;相反地,UDP 則不為 IP 環境提供可靠性等功能。所以 TCP 是比較針對可靠性的應用。
本文針對 TCP,也就是網路通訊協定,來實作基本的功能。

server 端程式

var net = require('net'); // 引入網路(Net)模組
var HOST = '127.0.0.1'; // 定義伺服器位址
var PORT = 8877; // 定義 Port

// 使用 net.ServerClient() 方法建立一個 TCP 伺服器
// 傳入 net.ServerClient() 的 callback 將作為 connection 事件的處理函數
var server = net.createServer();

// 監聽 listening 事件
server.on('listening', function(){
  console.log('Server is listening on port', PORT);

  // 如需 IP 位址等資訊,可藉由以下方式來取得
  var addr = server.address();
  console.log('%j', addr); // {"address":"127.0.0.1","family":"IPv4","port":8877}
});

// 監聽 connection 事件
server.on('connection', function(socket){
  console.log('Server has a new connection');
  console.log('bSockData 的值:' + bSockData);
  if(bSockData){
    socket.resume(); // 恢復通訊端(socket) data 事件
    bSockData = false;
  }else{
    socket.pause(); // 暫停通訊端(socket) data 事件
    bSockData = true;
  }
  console.log(socket.address()); // 此方法與 server.address() 得到的結果會是一致的,因為 socket.address() 方法鎖定的就是伺服器的 IP 位址
  console.log(socket.localAddress); // 取得 server 的 IP:127.0.0.1
  console.log(socket.localPort); // 取得 server 的 PORT:8877
  console.log('client 端的 IP:' + socket.remoteAddress); // client 端的 IP:127.0.0.1
  console.log('client 端的 PORT:' + socket.remotePort); // client 端的 PORT:61929

  socket.on('data', function(data){

    if(socket.bytesRead > 32){
      console.info('DATA ' + socket.remoteAddress + ' : "' + 'is too long!' + '"');
    }else{
      console.info('DATA ' + socket.remoteAddress + ' : "' + data + '"');
    }

    // 輸出由 client 端發來的資料位元組長度
    console.info('socket.bytesRead is ' + socket.bytesRead);
    console.info('DATA ' + socket.remoteAddress + ' : "' + data + '"');

    // 回發資料,用戶端將收到來自服務端的資料
    socket.write('Server write: "' + data + '"');
    // 輸出回發到用戶端的資料位元組長度
    console.info('socket.bytesWritten is ' + socket.bytesWritten);
  });

  server.close(); // 會觸發 close 方法,客戶端使用 client.end() 之後,才會呼叫。
});

// 監聽 close 事件
server.on('close', function(){
  console.log('Server is now closed');
});

// 監聽指定的 Port
server.listen(PORT, HOST); // 會觸發 listening 方法

client 端程式

var net = require('net'); // 引入網路 (Net) 模組
var HOST = '127.0.0.1';
var PORT = 8877;

// 使用 net.connect() 方法,建立一個 TCP 用戶端 instance
var client = net.connect(PORT, HOST, function(){
  console.log('客戶端連線…');

  // 向伺服器端發送資料,該方法其實就是 socket.write() 方法,因為 client 參數就是一個通訊端的物件
  client.write('client write: 哈囉 Server!');
  client.end();
});

// data 事件
client.on('data', function(data){
  console.log(data.toString());

  // 輸出由 client 端發來的資料位元組長度
  console.log('socket.bytesRead is ' + client.bytesRead);

  // 在列印輸出資料後,執行關閉用戶端的操作,其實就是 socket.end() 方法
  client.end();
});

// end 事件
client.on('end', function(){
  console.log('client disconnected');
});

藉著先執行 server 端程式,如下圖顯示:

再執行 client 端程式,如下圖顯示:

再回去看 server 端的顯示,如下圖,會多出幾行,可籍此得知各事件觸發的順序:

取得目前的 client 端連線數

只要在 connection 這個監聽事件中,透過 server.getConnections() 即可取得,如下範例:

// 監聽 connection 事件
server.on('connection', function(){
  console.log('Server has a new connection');
  server.getConnections(function(err, count){
    if(err){
      console.info(err.message);
    }else{
      console.info("目前的連線數:" + count);
    }
  });
  //server.close(); // 會觸發 close 方法,客戶端使用 client.end() 之後,才會呼叫。
});

您可在此處留言

搶先留言!

Notify of
avatar
wpDiscuz