使用 C++ 和 Boost(或不使用?)检查是否正在使用特定端口?
Using C++ and Boost (or not?) to check if a specific port is being used?
我正在尝试检查 C++ 中是否正在使用特定端口。我不会出于任何原因试图让 C++ 程序在该端口上侦听,只是检查它是否正在被使用。将有另一个程序侦听该端口,如果它停止,我希望我的程序做一些事情。所以,它会每 10 秒左右检查一次,如果端口正在使用,它什么都不做,但如果端口可用,就会发生一些事情。
我一直在查看 boost ASIO 库,但我似乎无法弄清楚如何完成它。
这里有两个选项。
如果您真的想检查端口是否被使用,只需尝试绑定:
bool port_in_use(unsigned short port) {
using namespace boost::asio;
using ip::tcp;
io_service svc;
tcp::acceptor a(svc);
boost::system::error_code ec;
a.open(tcp::v4(), ec) || a.bind({ tcp::v4(), port }, ec);
return ec == error::address_in_use;
}
实时查看:Live On Coliru,正确打印
Port 1078 is in use
CAVEAT there could be other reasons why you can't bind to a local endpoint; check that you have the required permissions first (the permission error is being swallowed here)
如果您真的想检查连接是否被接受,则必须建立连接。这可能会更耗时,因此您可能希望 运行 在超时的情况下执行此操作:
bool accepting_connections(unsigned short port) {
using namespace boost::asio;
using ip::tcp;
using ec = boost::system::error_code;
bool result = false;
try
{
io_service svc;
tcp::socket s(svc);
deadline_timer tim(svc, boost::posix_time::seconds(1));
tim.async_wait([&](ec) { s.cancel(); });
s.async_connect({{}, port}, [&](ec ec) {
result = !ec;
});
svc.run();
} catch(...) { }
return result;
}
测试:
int main() {
using namespace std;
if (accepting_connections(22))
cout << "Port 22 is accepting connections\n";
}
正如@sehe所说,尝试绑定是一种正确的方式。
a.bind({ tcp::v4(), port }, ec)
该方法仅检测端口是否在 0.0.0.0:port
上使用。
如果你想看看你的程序是否可以监听127.0.0.1:port
(它们是不同的套接字),试试
a.bind(tcp::endpoint(ip::address::from_string("127.0.0.1"), port), ec)
我正在尝试检查 C++ 中是否正在使用特定端口。我不会出于任何原因试图让 C++ 程序在该端口上侦听,只是检查它是否正在被使用。将有另一个程序侦听该端口,如果它停止,我希望我的程序做一些事情。所以,它会每 10 秒左右检查一次,如果端口正在使用,它什么都不做,但如果端口可用,就会发生一些事情。
我一直在查看 boost ASIO 库,但我似乎无法弄清楚如何完成它。
这里有两个选项。
如果您真的想检查端口是否被使用,只需尝试绑定:
bool port_in_use(unsigned short port) {
using namespace boost::asio;
using ip::tcp;
io_service svc;
tcp::acceptor a(svc);
boost::system::error_code ec;
a.open(tcp::v4(), ec) || a.bind({ tcp::v4(), port }, ec);
return ec == error::address_in_use;
}
实时查看:Live On Coliru,正确打印
Port 1078 is in use
CAVEAT there could be other reasons why you can't bind to a local endpoint; check that you have the required permissions first (the permission error is being swallowed here)
如果您真的想检查连接是否被接受,则必须建立连接。这可能会更耗时,因此您可能希望 运行 在超时的情况下执行此操作:
bool accepting_connections(unsigned short port) {
using namespace boost::asio;
using ip::tcp;
using ec = boost::system::error_code;
bool result = false;
try
{
io_service svc;
tcp::socket s(svc);
deadline_timer tim(svc, boost::posix_time::seconds(1));
tim.async_wait([&](ec) { s.cancel(); });
s.async_connect({{}, port}, [&](ec ec) {
result = !ec;
});
svc.run();
} catch(...) { }
return result;
}
测试:
int main() {
using namespace std;
if (accepting_connections(22))
cout << "Port 22 is accepting connections\n";
}
正如@sehe所说,尝试绑定是一种正确的方式。
a.bind({ tcp::v4(), port }, ec)
该方法仅检测端口是否在 0.0.0.0:port
上使用。
如果你想看看你的程序是否可以监听127.0.0.1:port
(它们是不同的套接字),试试
a.bind(tcp::endpoint(ip::address::from_string("127.0.0.1"), port), ec)