端口扫描遇到问题~ 求助~
发布于 7 年前 作者 smarttang 2944 次浏览 来自 问答

模仿开源项目: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();
    });
}
1 回复

改写了下,还是有问题,始终无法正确停止。。。。

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(callback){
    var results = [];
    var count = this.tasklist.length;
    for (var i = 0; i < this.tasklist.length; i++){
        var check = net.connect(
            this.tasklist[i],
            () => {
                results.push(this.tasklist[i]);
                check.destroy();
            })
        check.on('close', () => {
            console.log(count);
            // destroy() 之后就会到这
            // 计数器自减
            count--;
            if (count === 0){
                console.log(results);
                // 扫描完成
                callback(results);
            }
        });
        // 出现异常就断开
        check.on('error',(err) =>{
            console.log(err);
            check.destroy();
        });
        // 设置超时
        check.setTimeout(1,function(){
            check.destroy();
        });
    }
    // async.each(this.tasklist,function(item){
    //     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!!');
    //         }
    //         this.destroy();
    //     });
    // });
}
回到顶部