Node.js開發入門—套接字(socket)編程


Node.js的net模塊提供了socket編程接口,方便我們利用較為底層的套接字接口來實現應用協議。這次我們看一個簡單的回顯服務器示例,包括服務端和客戶端的代碼。

代碼

分服務器和客戶端兩部分來說吧。

server代碼分析

server.js:

var net = require("net");

// server is an instance of net.Server
// sock is an instance of net.Socket
var server = net.createServer(function(sock){
  console.log('client connected, address -  ', sock.remoteAddress, ' port - ', sock.remotePort);
  sock.setEncoding('utf8');
  sock.on('data', function(data){
    console.log('got data from client - ', data);
    sock.write(data);
  });

  sock.on('end', function(){
    console.log('client disconnected');
  });

  sock.on('error', function(err){
    console.log('socket error - ', err);
  });
});

server.maxConnections = 10;
server.listen(7, function(){
  console.log('echo server bound at port - 7');
});

使用net.createServer來創建一個服務器實例,這個方法的返回值是一個net.Server實例,net.Server提供了listen方法,讓我們監聽到某個端口上來接受客戶端連接,同時還提供了一些屬性,比如maxConnections可以設置服務器的並發連接數上限(當服務器的連接數超過這個值時,后續連接就會被拒掉),還有其它的,看文檔吧:https://nodejs.org/api/net.html#net_class_net_server。

net.Server還提供了一些事件,比如error、connection等。當有客戶端連接被接受時,會發射connection事件,這個事件帶一個net.Socket對象作為參數,可以在回調函數里訪問這個net.Socket實例來與客戶端交互。我在代碼里,給createServer方法傳入了一個callback來處理connection事件,實際上也可以略作修改,通過監聽connection事件的方法處理客戶端連接。新代碼如下:

var net = require("net");

var server = net.createServer();

server.on('connection', function(sock){
  console.log('client connected, address -  ', sock.remoteAddress, ' port - ', sock.remotePort);
  sock.setEncoding('utf8');
  sock.on('data', function(data){
    console.log('got data from client - ', data);
    sock.write(data);
  });

  sock.on('end', function(){
    console.log('client disconnected');
  });

  sock.on('error', function(err){
    console.log('socket error - ', err);
  });
});

server.maxConnections = 10;
server.listen(7, function(){
  console.log('echo server bound at port - 7');
});

效果是一樣的。

net.Socket對象有一些方法,比如write可以寫數據。還有一些事件,比如error、end、data等,看代碼就能明白用法。還有一些屬性,比如remoteAddress、remotePort。

client代碼分析

client.js:

var net = require("net");
var readline = require('readline');

console.log('type "exit" or "quit" to quit.');

// sock is an instance of net.Socket
var sock = net.connect({port: 7}, function(){
  console.log('server connected');
  sock.setEncoding('utf8');
  sock.write('Hello Echo Server\r\n');
});

sock.on('data', function(data){
  console.log('got data from server - ', data);
});

sock.on('end', function(){
  console.log('client disconnected');
});

sock.on('error', function(err){
  console.log('socket error - ', err);
});

sock.on('close', function(){
  console.log('echo client was closed');
  process.exit(0);
});

var rl = readline.createInterface({
  input: process.stdin
});

function quitEcho(){
  rl.close();
  sock.end();
  console.log('quit echo client');
}

rl.on('line', function(cmd){
  if(cmd.indexOf('quit') == 0 || cmd.indexOf('exit') == 0){
    quitEcho();
  }else{
    sock.write(cmd + '\r\n');
  }
});

rl.on('SIGINT', quitEcho);

調用readline模塊來從標准輸入讀取數據來發送給客戶端。readline的文檔在這里:https://nodejs.org/api/readline.html。正如它的名字,Readline可以讓你一行一行的讀取一個流。比較常見的就是讀取標准輸入流。Readline有一些事件,我們用到的“line”事件,在一行數據就緒時會發射,帶一個代表數據的參數。監聽line事件,在回調中調用net.Socket的write方法寫入數據。當你在控制台輸入“quit”或“exit”時,調用quitEcho退出。

net.connect方法可以連接到指定的服務器,它的原型如下:

net.connect(options[, connectionListener])

第一個參數是Object,用於指定和連接相關的選項,比如服務端的host、port等,如果不指定host,就默認用localhost作為服務端主機名.

net.connect返回net.Socket對象,一旦拿到了Socket實例,就可以用net.Socket來為所欲為了。監聽了data事件來接收服務端發揮的數據,監聽close事件來退出進程。net.Socket的具體API,參考https://nodejs.org/api/net.html#net_class_net_socket。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM