模仿开源项目:https://github.com/Lellansin/node-net-scan/tree/master/lib造轮子,发现基于async不能正常停止。。
var net = require('net');
var async = require("async");
var util = require("util");
var EventEmitter = require('events').EventEmitter;
function Snmap() {}
// 继承函数
util.inherits(Snmap,EventEmitter);
module.exports = new Snmap();
// 判断端口范围是否合法
var checkports = function(ports){
var port_split = ports.split('-');
if (Number(port_split[0]) < 1){
return false;
}
if (Number(port_split[1]) < 1 || Number(port_split[1]) > 65536){
return false;
}
return true;
};
// 初始化参数
Snmap.prototype.init = function(options) {
// 初始化目标
if (!net.isIPv4(options.target)){
var err = new Error('Can\'t not found target %s !!',options.target);
this.emit('error',err);
}
// 初始化扫描的端口范围
if (!checkports(options.port) && options.port != undefined){
var err = new Error('Can\'t not create ports %s !!',options.target);
this.emit('error',err);
}
this.target = options.target;
this.ports = [];
this.tasklist = [];
// 如果不设置端口范围,则默认用最全的范围
if (options.port == undefined){
for(var i=1; i<=65535; i++){
this.ports.push(i);
}
this.start = 1;
this.end = 65535;
}else{
// 解析端口范围
var ip_range = options.port.split('-');
for(var i=Number(ip_range[0]); i<=Number(ip_range[1]); i++){
this.ports.push(i);
}
this.start = Number(ip_range[0]);
this.end = Number(ip_range[1]);
}
// 拼装执行队列
for(var item in this.ports){
this.tasklist.push({'host':this.target,'port':Number(this.ports[item])});
}
}
// 执行扫描任务
Snmap.prototype.scan = function(){
var results = [];
var count = this.end - this.start;
async.eachLimit(this.tasklist,10,function(item,callback){
console.log('testing: '+item['host']+"/"+item['port']);
var conn = net.connect(item,
function(){
console.log('ip:%s,port:%s,status:open',item['host'],item['port']);
results.push(item);
this.destroy();
}
);
conn.on('error',function(err){
if (err.code != 'ECONNREFUSED'){
console.log('err',err.code,item['host']+'/'+item['port']);
}
this.destroy();
});
conn.on('close', function() {
console.log(count);
if (!count--) {
console.log('finish!!');
}
});
callback();
});
}