Using C++ and Boost (or not?) to check if a specific port is being used?

為{幸葍}努か 提交于 2020-01-13 19:57:34

问题


I am trying to check if a specific port is being used in C++. I am not trying to have the C++ program listen on that port for any reason, just check to see if it is being used. There will be another program listening on that port, and if it stops, I want my program to do something. So, it will check every 10 seconds or so, and if the port is in use, it will do nothing, but if the port becomes available, something will happen.

I've been looking at the boost ASIO library, but I can't seem to figure out how to accomplish this.


回答1:


There's two options here.

If you actually want to check the port is use, simply attempt a bind:

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;
}

See it live: Live On Coliru, correctly printing

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)

If you actually want to check that connections are being accepted, you will have to make a connection. This could be somewhat more time consuming so you might want to run this under a timeout:

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;
}

Test:

int main() {
    using namespace std;

    if (accepting_connections(22))
        cout << "Port 22 is accepting connections\n";
}



回答2:


Just as @sehe said, attempt to bind is a proper way.

a.bind({ tcp::v4(), port }, ec)

The method only detects if port is in use on 0.0.0.0:port.

If you want to see if your program can listen on 127.0.0.1:port(they are different sockets), try

a.bind(tcp::endpoint(ip::address::from_string("127.0.0.1"), port), ec)


来源:https://stackoverflow.com/questions/33358321/using-c-and-boost-or-not-to-check-if-a-specific-port-is-being-used

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!