【问题标题】:Find if a port is available to use in linux using c++使用 c++ 查找是否可以在 linux 中使用的端口
【发布时间】:2017-01-29 17:59:20
【问题描述】:

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

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

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

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

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

到目前为止一切顺利。

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

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

【问题讨论】:

  • 还有更多命令可以使用,比如whereis netstat 左右,并检查输出。
  • 请注意,您必须处理在检查和使用它之间端口不可用的情况。根据上下文,检查它是否可用是没有用的,或者最好在您想要检查的时候取得端口的所有权(如果最终不使用则释放)。
  • 不使用bind()有什么具体原因吗?
  • @karastojko,基本上我将在检查端口的可用性后通过触发 Tcl 命令(使用Tcl_Eval)在该端口上打开一个 Tcl 通信服务器。所以,我不想绑定端口,因为我必须在绑定后立即关闭。
  • @AProgrammer,这个案子已经处理好了。我使用了critical sectionmutex的一些概念。

标签: c++ linux port netstat


【解决方案1】:

一个更好的主意是让您的代码完全不使用netstat

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    command -v netstat
    

    如果netstat 二进制文件在$PATH 中可用,则该命令返回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 # ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      • 2013-02-11
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      相关资源
      最近更新 更多