Найти, доступен ли порт для использования в Linux с помощью переполнения стека

Я работаю над проектом 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 в другое время (т.е. без выполнения другой команды оболочки).

2

Решение

Еще лучшая идея — заставить ваш код работать полностью без netstat в целом.

В Linux все это netstat делает (для вашего случая использования) читать содержимое /proc/net/tcp, который перечисляет все используемые порты.

Все, что вам нужно сделать, это открыть /proc/net/tcp себя и разбери. Это становится обычным, скучным кодом для разбора файлов. Не может быть намного более «защищенным от сбоев», чем это.

Вы найдете документацию формата /proc/net/tcp в справочных страницах Linux.

В том маловероятном случае, что вам нужно проверить UDP порты, это было бы /proc/net/udp,

Конечно, между временем, когда вы проверяете, есть окно гонки /proc/net/tcpгде кто-то может захватить порт. Но это также верно с netstat также, и поскольку это будет намного более медленный процесс, это будет на самом деле улучшением и значительно сократит гоночный период.

4

Другие решения

Так как вы просите способ проверить, если 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 # ...
0

По вопросам рекламы [email protected]