Node.js对TCP/Socket的实现之net模块TCP服务端详解

 2015年08月08日    1788     声明


net模块可以创建TCP服务端,也可以创建TCP服务端客户端。创建一个TCP服务器,可以使用构造函数new net.Server()或使用其工厂方法net.createServer,这两种方法都会返回一个net.Server类,net.Server类继承了events,所以它也是个事件发射器。


  1. server.listen()方法与listening事件
  2. server.close()方法与close事件
  3. server.address()方法
  4. 获取连接数server.getConnections(callback)与设置连接数server.maxConnections
  5. server.unref()server.ref()


1. server.listen()方法与listening事件

创建server对象后,通过listen()方法启动服务器监听。监听对象可以是一个端口,可以是一个UNIX socket套接字。server.listen()可以是以下4种形式:

  • server.listen(port[, host][, backlog][, callback]):在指定端口 port 和主机 host 上开始接受连接。如果省略 host 则服务器会接受来自所有 IPv4 地址(INADDR_ANY)的连接;端口为 0 则会使用分随机分配的端口。

    backlog:积压量,为连接等待队列的最大长度。实际长度由您的操作系统通过 sysctl 设置决定,比如 Linux上的 tcp_max_syn_backlogsomaxconn。该参数缺省值为 511(不是 512)。

  • server.listen(path[, callback]):在指定UNIX socket套接字上监听连接,path套接字服务器所在路径。
  • server.listen(handle, [callback]):在指定的句柄接受连接,指定的件描述符或者句柄已经被绑定在特定的端口或者套接字上。handle变量可以为server或者socket(任一以下划线开头的成员_handle), 或者一个 {fd: } 对象。此方法在Windows上不适用。
  • server.listen(options[, callback]):在指定对象上开始开始接受连接,这个方法会根据对象参数调用上面三个方法之一。options对象参数可以是下面形式:
    • port {Number} - 可选,端口
    • host {String} - 可选,主机
    • backlog {Number} - 可选,积压量
    • path {String} - 可选,套接字路径
    • exclusive {Boolean} - 可选,如果参数是false(默认值),集群进程将会使用同一个句柄,允许连接共享。当参数是 true时,句柄不会共享,如果共享端口会返回错误。

当服务器调用server.listen()方法启动监听时,会触发listening事件,方法最后一个参数[, callback]会被用做listening事件的监听器,也可以通过server.on('listening')创建监听器。

var net = require('net');
var server = new net.Server(function(connection) {
    connection.on('end', function() {
        console.log('客户端连接断开');
    });
    //向客户端写入数据
    connection.write('hello\r\n');
    connection.pipe(connection);
});

//TCP服务器开始端口监听
server.listen(2345);

//listening事件监听
server.on('listening',  function() {
    console.log('TCP服务启动');
});


2. server.close()方法与close事件

server.close()方法会使用服务器停止接收新的连接,保持现有连接,当所有连接结束的时候服务器会关闭,并会触发close事件。可以传一个回调函数来监听close事件,监听方法可接受一个参数,参数内容为错误信息。

 //close事件监听
server.close(function(err) {
    if(err){
	console.error(err);
    }
    console.log('服务器已断开');
});


3. server.address()方法

server.address()方法会返回操作系统报告的绑定的地址,协议族和端口。server.address()方法需要在,server.listen()方法之后调用。对查找操作系统分配的地址哪个端口已被分配非常有用, 如: { port: 12346, family: 'IPv4', address: '127.0.0.1' }

server.listen(2345, function() {
    var address = server.address();
    console.log('TCP服务启动');
});


4. 获取连接数server.getConnections(callback)与设置连接数server.maxConnections

server.maxConnections属性用于服务器最大连接数,当服务器连接数超过数量时会拒绝连接。但不推荐使用这个选项,在套接字已经用child_process.fork()发送给子进程。

server.getConnections(callback)方法可以异步获取服务器当前活跃的连接数,用于套接字发送给子进程。回调方法callback有两个参数errcount。此方法是server.connections方法的替代方法。


5. server.unref()server.ref()

server.unref()如果当前系统是事件系统中唯一一个活动的服务器,调用 unref 将允许程序退出。如果服务器已被 unref,则再次调用 unref 并不会产生影响。

server.ref()方法与unref相反,如果当前系统是事件系统中唯一的服务器,在一个之前被unref了的服务器上,调用ref方法将使程序不会退出(缺省行为)。如果服务器已经被 ref,则再次调用ref并不会产生影响。

server.unref();  //如果不调用ref(),将导致程序退出
server.ref();    //调用此方法后,程序不会再退出