使用 C++ 查找端口是否可以在 Linux 中使用

Sur*_*ati 3 c++ linux port netstat

我正在开发一个 C++ 项目。为了满足其中一项要求,我需要随时检查端口是否可在我的应用程序中使用。为了实现这一点,我提出了以下解决方案。

#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <string>
#include <stdio.h>


std::string _executeShellCommand(std::string command) {
    char buffer[256];
    std::string result = "";
    const char * cmd = command.c_str();
    FILE* pipe = popen(cmd, "r");
    if (!pipe) throw std::runtime_error("popen() failed!");

    try {
        while (!feof(pipe)) 
            if (fgets(buffer, 128, pipe) != NULL)
                result += buffer;
    } catch (...) {
        pclose(pipe);
        throw;
    }
    pclose(pipe);
    return result;
}

bool _isAvailablePort(unsigned short usPort){
    char shellCommand[256], pcPort[6];
    sprintf(shellCommand, "netstat -lntu | awk '{print $4}' | grep ':' | cut -d \":\" -f 2 | sort | uniq | grep %hu", usPort);
    sprintf(pcPort, "%hu", usPort);

    std::string output =  _executeShellCommand(std::string(shellCommand));

    if(output.find(std::string(pcPort)) != std::string::npos)
            return false;
    else
            return true;

}   


int main () {
    bool res = _isAvailablePort(5678);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

基本上,该_executeShellCommand函数可以随时执行任何 shell 命令,并可以将stdout输出作为返回字符串返回。

我正在该函数中执行以下 shell 命令。

netstat -lntu | awk '{print $4}' | grep ':' | cut -d \":\" -f 2 | sort | uniq | grep portToCheck
Run Code Online (Sandbox Code Playgroud)

因此,如果端口已在使用中,则将_executeShellCommand返回 PortValue 本身,否则将返回 Blank。因此,检查返回的字符串,我可以决定。

到目前为止,一切都很好。

现在,我想让我的项目完全防崩溃。因此,在触发netstat命令之前,我想确定它是否真的存在。在这种情况下我需要帮助。netstat我知道,怀疑Linux 机器中命令的可用性有点愚蠢。我只是想到一些用户netstat出于某种原因从他的机器中删除了二进制文件。

注意:我不想打电话bind()来检查端口是否可用。netstat另外,如果我可以检查命令是否可用而无需_executeShellCommand再次调用(即无需执行另一个 Shell 命令), 那将是最好的。

Sam*_*hik 5

更好的想法是让您的代码完全无需完全工作netstat

在 Linux 上,netstat(针对您的用例)所做的一切都是读取 的内容/proc/net/tcp,它枚举了所有正在使用的端口。

您所要做的就是打开/proc/net/tcp自己并解析它。这只是一个普通的、无聊的文件解析代码。没有比这更“防碰撞”的了。

您可以在 Linux 手册页中找到该格式的文档/proc/net/tcp

万一您需要检查UDP端口,这将是/proc/net/udp.

当然,在你检查的时间之间有一个竞争窗口/proc/net/tcp,有人可以抢占端口。但这也是如此netstat,因为这将是一个慢得多的过程,这实际上将是一个改进,并显着减少竞争窗口。