node.js的net模块的socket.setTimeout(time,[fun(){}])的使用方法及测试

2015-12-9 10:49:09

之前的socket服务器未对超时的socket做处理,客户端通信不通自动断开之后,服务器因不知情而一直维护着socket链接,而断开的客户端会重新申请一个新的连接占用新的端口,时间长了之后就会有大量的假连接占用了大量的端口。可以使用socket.setTimeout(time,[fun(){}])方法断开空闲的链接。

server.js

var net = require('net');

var server = net.createServer(function(socket) {
  socket.on('data', function (data) {
    console.log(data.toString());
    socket.write(data);
  });

  socket.on('end', function() {
    console.log('客户端已断开');
  });

  socket.on('error', function() {
    console.log('客户端错误');
  });

  var waitTime = 3;

  //设置超时时间
  socket.setTimeout(1000 * waitTime,function() {
    console.log('客户端在' + waitTime + 's内未通信,将断开连接...');
  });
  //监听到超时事件,断开连接
  socket.on('timeout', function() {
    socket.end();
  });
});

server.listen(8124, function() {
  console.log('服务器启动');
});

client.js

var net = require('net');

var client = net.connect({port: 8124},function() {
  console.log('client connected');
  client.write('hello world!
');
});

client.on('data', function(data) {
  console.log(data.toString());
  // client.write(data);
});

client.on('end', function() {
  console.log('服务器断开连接');
});

 也可以将socket.end()放到setTimeout(time,fun(){})的回调函数fun()中,这样就不用再设置对事件'timeout'的监听函数。

如果是确认客户端已经断开连接了(比如客户端会定时发送心跳包,现在已经超过间隔时间然而没有发送),可以使用socket.destroy()来断开连接。使用socket.end()断开连接的话由于服务器端发送的fin包不能收到反应,会使此链接进入TIME_WAIT状态,如果客户端一直没有回应,在2-4分钟之后才会关闭链接,而destory()会直接断开链接,显然更加高效。

参考链接:TCP协议三次握手连接四次握手断开和DOS攻击  

网络的FIN_WAIT_2状态解释和分析

原文地址:https://www.cnblogs.com/lswit/p/5032157.html