#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <signal.h>
#include <iostream>
#include <string>
#include <vector>
class net_utility {
public:
static void listened_host_list(const char *domain, const char *port, std::vector<std::string>&host_list) {
signal(SIGPIPE, SIG_IGN);
addrinfo *result = nullptr;
addrinfo hints = { 0 };
hints.ai_family = AF_UNSPEC; // either IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;
if (0 != getaddrinfo(domain, port, &hints, &result)) {
std::cerr << "getaddrinfo for domain:" << domain << " port:" << port << "failed." << std::endl;
return;
}
char address[INET6_ADDRSTRLEN] = "";
const char *retval = nullptr;
struct timeval timeo = {10, 0}; // 10s
socklen_t len = sizeof(timeo);
for (auto addr = result;addr != nullptr;addr = addr->ai_next) {
int client_fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (client_fd < 0) {
continue;
}
setsockopt(client_fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len);
if (connect(client_fd, addr->ai_addr, addr->ai_addrlen) < 0) {
std::cerr << "connect failed." << std::endl;
close(client_fd);
continue;
}
switch(addr->ai_family) {
case AF_INET:
retval = inet_ntop(addr->ai_family, &(reinterpret_cast<sockaddr_in *>(addr->ai_addr)->sin_addr), address, INET6_ADDRSTRLEN);
break;
case AF_INET6:
retval = inet_ntop(addr->ai_family, &(reinterpret_cast<sockaddr_in6 *>(addr->ai_addr)->sin6_addr), address, INET6_ADDRSTRLEN);
break;
default:
retval = nullptr;
break;
}
host_list.emplace_back(address);
close(client_fd);
}
freeaddrinfo(result);
}
};
int main(){
const char *ip = "192.168.2.109";
const char *port = "26311";
std::vector<std::string>host_list;
net_utility::listened_host_list(ip, port, host_list);
for (auto &host : host_list) {
std::cout << host << " is listening" << std::endl;
}
return 0;
}