I am working on a C++ Project. To fulfill one of the requirement, I need to check if a port is available for using in my application anytime. To fulfill this , I have come to this following solution.
#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 Basically the _executeShellCommand
function can excute any shell command anytime and can return the stdout
output as return string.
And I am executing the following shell command in that function.
netstat -lntu | awk '{print $4}' | grep ':' | cut -d \":\" -f 2 | sort | uniq | grep portToCheck
So, if the port is already in use, the _executeShellCommand
will return the PortValue itself, else it will return Blank. So, checking the returned string, I can decide.
So far so good.
Now, I want to be make my Project completely Crash-proof. So, before firing the netstat
command, I want to make sure if it really exists or not. I want help in this case. I know, It's kind of stupid to doubt the availability of netstat
command in a linux machine. I am just thinking of some user who removed netstat
binary from his machine for some reason.
N.B. : I don't want make a bind()
call to chack if the port is available or not. Also, it will be best if I can check if netstat
command is available without calling _executeShellCommand
for another time (i.e. without executing another Shell Command).
An even better idea is to make your code work completely without netstat
altogether.
On Linux, all that netstat
does (for your use case) is read the contents of /proc/net/tcp
, which enumerates all ports in use.
All you have to do is open /proc/net/tcp
yourself, and parse it. This becomes just an ordinary, boring, file parsing code. Can't get much more "crash-proof" than that.
You will find the documentation of the format of /proc/net/tcp
in Linux manual pages.
In the unlikely event that you need to check UDP
ports, this would be /proc/net/udp
.
Of course, there is a race window between the time you check /proc/net/tcp
, where someone can grab the port. But that's also true with netstat
as well, and since that's going to be a much slower process, this will actually be an improvement, and reduce the race window significantly.