【发布时间】:2021-09-06 00:42:19
【问题描述】:
如何检查localhost 的端口是否繁忙?
有没有标准算法?我正在考虑向该网址发出http 请求并检查响应状态代码是否不是404。
【问题讨论】:
-
portfinder 很棒 :) 顺便提一下,它有默认端口选项:
portfinder.getPortPromise({port: 3000})...
标签: javascript node.js
如何检查localhost 的端口是否繁忙?
有没有标准算法?我正在考虑向该网址发出http 请求并检查响应状态代码是否不是404。
【问题讨论】:
portfinder.getPortPromise({port: 3000})...
标签: javascript node.js
您可以尝试启动服务器,无论是 TCP 还是 HTTP,都没有关系。然后你可以尝试开始监听一个端口,如果失败,检查错误码是不是EADDRINUSE。
var net = require('net');
var server = net.createServer();
server.once('error', function(err) {
if (err.code === 'EADDRINUSE') {
// port is currently in use
}
});
server.once('listening', function() {
// close the server if listening doesn't fail
server.close();
});
server.listen(/* put the port to check here */);
使用一次性事件处理程序,您可以将其包装到异步检查函数中。
【讨论】:
SO_REUSEADDR 的服务器。查看github.com/baalexander/node-portscanner 了解他们如何使用net.Socket() 解决此问题。
server.once('close', () => { myFunc() }).close()
查看惊人的tcp-port-used node module!
//Check if a port is open
tcpPortUsed.check(port [, host])
//Wait until a port is no longer being used
tcpPortUsed.waitUntilFree(port [, retryTimeMs] [, timeOutMs])
//Wait until a port is accepting connections
tcpPortUsed.waitUntilUsed(port [, retryTimeMs] [, timeOutMs])
//and a few others!
我已经在我的gulpwatch 任务中使用这些来检测我的 Express 服务器何时安全终止以及何时再次启动。
这将准确报告端口是否已绑定(无论SO_REUSEADDR 和SO_REUSEPORT,如@StevenVachon 所述)。
portscanner NPM module 将在范围内为您找到空闲和使用的端口,如果您试图找到要绑定的开放端口,它会更有用。
【讨论】:
tcpPortUsed 在侦听 telnet 的端口应答时显示端口正在使用。我有一项服务只接受一个连接并拒绝 telnet。在这种情况下,它返回端口未使用。
tcpPortUsed 尝试与端口建立 TCP 连接(不是 telnet - 尽管 telnet 做同样的事情)。如果它能够建立连接,则该端口正在使用中。如果不是,则端口是空闲的。所以我不确定你的意思 - 服务在接受它之前无法知道 TCP 连接是来自 telnet 还是来自其他任何东西。
SO_REUSEPORT 或SO_REUSEADDR 打开的,那么该端口可能会被多个应用程序打开——尽管您不太可能在您的情况下设置这个。只是另一个需要考虑的极端情况
感谢 Steven Vachon 链接,我做了一个简单的例子:
const net = require("net");
const Socket = net.Socket;
const getNextPort = async (port) => {
return new Promise((resolve, reject) => {
const socket = new Socket();
const timeout = () => {
resolve(port);
socket.destroy();
};
const next = () => {
socket.destroy();
resolve(getNextPort(++port));
};
setTimeout(timeout, 200);
socket.on("timeout", timeout);
socket.on("connect", function () {
next();
});
socket.on("error", function (exception) {
if (exception.code !== "ECONNREFUSED") {
reject(exception);
} else {
next();
}
});
socket.connect(port, "0.0.0.0");
});
};
getNextPort(8080).then(port => {
console.log("port", port);
});
【讨论】: