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!\r\n');
});

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狀態解釋和分析


免責聲明!

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



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