使用c++查找在linux中是否可以使用端口

Find if a port is available to use in linux using c++

本文关键字:可以使 是否 c++ 查找 linux 使用      更新时间:2023-10-16

我正在做一个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;
}

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

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

netstat -lntu | awk '{print $4}' | grep ':' | cut -d ":" -f 2 | sort | uniq | grep portToCheck

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

到目前为止还不错。

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

注意:如果端口可用或不可用,我不想打bind()来查询。此外,如果我可以在不再次调用_executeShellCommand的情况下(即,不执行另一个Shell命令(检查netstat命令是否可用,那将是最好的。

一个更好的想法是让您的代码完全在没有netstat的情况下工作。

在Linux上,netstat所做的(对于您的用例(就是读取/proc/net/tcp的内容,它列举了所有正在使用的端口。

你所要做的就是自己打开/proc/net/tcp并解析它。这只是一个普通的、无聊的文件解析代码。再也找不到比这更"防碰撞"的了。

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

在不太可能的情况下,您需要检查UDP端口,这将是/proc/net/udp

当然,在你检查/proc/net/tcp的时间之间有一个竞争窗口,在那里有人可以抢端口。但netstat也是如此,由于这将是一个慢得多的过程,这实际上是一个改进,并显著缩短了竞争窗口。

由于您正在寻求一种方法来检查netstat命令是否可用,因此我不会尝试在C++中建议其他方法。shell方法是检查以下命令的返回代码:

command -v netstat

如果$PATH中有netstat二进制,则命令返回0。在Bash中,它通常看起来是这样的:

command -v netstat
if [ $? -eq 0 ]; then
  netstat # ...
else
  echo >&2 "Error: netstat is not available"
fi

或者只是

command -v netstat >/dev/null && netstat # ...