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。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!