Я работаю над проектом 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
Функция может выполнить любую команду оболочки в любое время и может вернуть stdout
выводить как возвращаемую строку.
И я выполняю следующую команду оболочки в этой функции.
netstat -lntu | awk '{print $4}' | grep ':' | cut -d \":\" -f 2 | sort | uniq | grep portToCheck
Итак, если порт уже используется, _executeShellCommand
вернет само PortValue, иначе он вернет значение Blank. Итак, проверяя возвращаемую строку, я могу решить.
Все идет нормально.
Теперь я хочу сделать свой проект полностью защищенным от сбоев. Итак, перед тем как уволить netstat
Команда, я хочу убедиться, существует ли она на самом деле или нет. Я хочу помочь в этом случае. Я знаю, это глупо сомневаться в наличии netstat
Команда в машине Linux. Я просто думаю о каком-то пользователе, который удалил netstat
бинарный со своей машины по какой-то причине.
Нотабене : Я не хочу делать bind()
позвонить в Chack, если порт доступен или нет. Кроме того, будет лучше, если я смогу проверить, netstat
команда доступна без звонка _executeShellCommand
в другое время (т.е. без выполнения другой команды оболочки).
Еще лучшая идея — заставить ваш код работать полностью без netstat
в целом.
В Linux все это netstat
делает (для вашего случая использования) читать содержимое /proc/net/tcp
, который перечисляет все используемые порты.
Все, что вам нужно сделать, это открыть /proc/net/tcp
себя и разбери. Это становится обычным, скучным кодом для разбора файлов. Не может быть намного более «защищенным от сбоев», чем это.
Вы найдете документацию формата /proc/net/tcp
в справочных страницах Linux.
В том маловероятном случае, что вам нужно проверить UDP
порты, это было бы /proc/net/udp
,
Конечно, между временем, когда вы проверяете, есть окно гонки /proc/net/tcp
где кто-то может захватить порт. Но это также верно с netstat
также, и поскольку это будет намного более медленный процесс, это будет на самом деле улучшением и значительно сократит гоночный период.
Так как вы просите способ проверить, если netstat
команда доступна, я не буду пытаться предложить другие пути в C ++. Способ оболочки проверяет код возврата следующей команды:
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 # ...