我正在开发一个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
命令之前,我想确定它是否真的存在。在这种情况下我需要帮助。我知道,怀疑linux机器中netstat
命令的可用性是多么愚蠢。我只想到一些用户出于某种原因从他的机器中删除了netstat
二进制文件。
N.B。 :如果端口可用,我不希望对{chack}进行bind()
调用。此外,如果我可以检查netstat
命令是否可用而不再调用_executeShellCommand
(即不执行另一个Shell命令),那将是最好的。
答案 0 :(得分:4)
更好的想法是让您的代码完全不使用netstat
。
在Linux上,netstat
执行的所有操作(针对您的用例)都会读取/proc/net/tcp
的内容,其中列出了所有正在使用的端口。
您所要做的就是自己打开/proc/net/tcp
并解析它。这变成了一个普通的,无聊的文件解析代码。无法获得更多&#34;防撞&#34;不止于此。
您可以在Linux手册页中找到/proc/net/tcp
格式的文档。
万一您需要检查UDP
个端口,这将是/proc/net/udp
。
当然,在您检查/proc/net/tcp
之间有一个竞赛窗口,有人可以抓住该端口。但是netstat
也是如此,并且由于这将是一个慢得多的过程,这实际上是一个改进,并且显着减少了竞赛窗口。
答案 1 :(得分:0)
由于您要求检查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 # ...