端口扫描器无法显示开放端口问题求助
端口扫描器无法显示开放端口
我编写了一个端口扫描器,但执行后无法显示开放端口,实际执行输出如下:
Enter command: portscanner Enter host: 127.0.0.1 Enter start port: 1 Enter end port: 3306 Enter Command:
相关代码如下:
Main.js
//Imports import readLine from 'readline-sync'; import { portScanner } from "../commands/Portscanner.js"; while(true) { let getCommand = readLine.question('Enter Command: '); switch(getCommand) { default: console.log("Try again"); break; case "portscanner": let host = readLine.question('Enter host: '); let startPort = Number(readLine.question('Enter start Port: ')); let endPort = Number(readLine.question('Enter end Port: ')); portScanner(host, startPort, endPort); break; } }
Portscanner.js
import net from 'net'; function portScanner(host, startPort, endPort) { const openPorts = []; for (let port = startPort; port <= endPort; port++) { const socket = new net.Socket(); socket.connect(port, host, () => { openPorts.push(port); console.log("Open: " + port); socket.end(); }); socket.on('error', () => { socket.destroy(); }); } setTimeout(() => { console.log("Open Ports:"); console.log(openPorts); }, 5000); } export {portScanner};
我已经在多个Discord服务器及ChatGPT上寻求过帮助,但问题仍未解决。
问题原因分析
- 无连接超时设置:
net.Socket默认无超时限制,部分端口的连接请求可能长时间挂起,无法触发connect或error事件,导致端口状态无法被捕获。 - 并发过高:一次性创建上千个Socket连接,会触发系统文件描述符限制,大量连接被直接拒绝,同时部分连接无法及时完成。
- 固定超时不可靠:硬编码的5秒等待时间无法适配不同网络环境,可能在部分连接完成前就输出结果,或浪费不必要的等待时间。
修复方案
修改Portscanner.js,加入超时控制、并发限制,并使用Promise管理所有异步扫描任务:
import net from 'net'; // 控制并发数,避免系统资源耗尽 const CONCURRENT_LIMIT = 50; function scanPort(host, port) { return new Promise((resolve) => { const socket = new net.Socket(); // 设置连接超时时间 socket.setTimeout(1000); socket.on('connect', () => { console.log(`Open: ${port}`); socket.end(); resolve(port); }); socket.on('timeout', () => { socket.destroy(); resolve(null); }); socket.on('error', () => { socket.destroy(); resolve(null); }); socket.connect(port, host); }); } async function portScanner(host, startPort, endPort) { const openPorts = []; const ports = Array.from({ length: endPort - startPort + 1 }, (_, i) => startPort + i); // 分批处理端口,控制并发 for (let i = 0; i < ports.length; i += CONCURRENT_LIMIT) { const batch = ports.slice(i, i + CONCURRENT_LIMIT); const results = await Promise.all(batch.map(port => scanPort(host, port))); // 收集开放的端口 results.forEach(port => { if (port) openPorts.push(port); }); } console.log("\nOpen Ports:"); console.log(openPorts.sort((a, b) => a - b)); } export { portScanner };
修复说明
- 超时控制:每个Socket连接设置1秒超时,避免长时间挂起。
- 并发限制:每次同时扫描50个端口,平衡扫描速度和系统资源占用。
- 异步任务管理:使用
Promise.all和async/await等待所有扫描任务完成后再输出结果,确保不会遗漏任何端口状态。
内容的提问来源于stack exchange,提问作者Jonaskop44
相关产品推荐
相关产品推荐

