Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to "it looks weird" "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.

All versions of both standards since then (C99 and C++98) have maintained the same idea. We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function. Reasons against omitting seem to boil down to "it looks weird". If, like me, you're curious about the rationale for the change to the C standard read this question. Also note that in the early 1990s this was considered "sloppy practice" because it was undefined behavior (although widely supported) at the time.

added full program with compilation instructions
Source Link
Edward
  • 67.2k
  • 4
  • 120
  • 284

Putting it all together

Here's how to do it:

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
#include <future>
#include <cstring>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
std::string isPortOpen(const std::string &domain, const std::string &port)
{
 addrinfo *result;
 addrinfo hints{}; 
 hints.ai_family = AF_UNSPEC; // either IPv4 or IPv6
 hints.ai_socktype = SOCK_STREAM; 
 char addressString[INET6_ADDRSTRLEN];
 const char *retval = nullptr;
 if (0 != getaddrinfo(domain.c_str(), port.c_str(), &hints, &result)) {
 return "";
 }
 for (addrinfo *addr = result; addr != nullptr; addr = addr->ai_next) {
 int handle = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
 if (handle == -1) {
 continue;
 }
 if (connect(handle, addr->ai_addr, addr->ai_addrlen) != -1) {
 switch(addr->ai_family) {
 case AF_INET:
 retval = inet_ntop(addr->ai_family, &(reinterpret_cast<sockaddr_in *>(addr->ai_addr)->sin_addr), addressString, INET6_ADDRSTRLEN);
 break;
 case AF_INET6:
 retval = inet_ntop(addr->ai_family, &(reinterpret_cast<sockaddr_in6 *>(addr->ai_addr)->sin6_addr), addressString, INET6_ADDRSTRLEN);
 break;
 default:
 // unknown family
 retval = nullptr;
 }
 close(handle);
 break;
 }
 }
 freeaddrinfo(result);
 return retval==nullptr ? "" : domain + ":" + retval + "\n";
}
int main(int argc, char *argv[]) {
 if (argc != 6) {
 std::cerr << "Usage: " << argv[0] << " domains.txt port threads timeout output.txt\n";
 std::exit(-1);
 }
 std::string domains_file = argv[1];
 std::string output_file = argv[5];
 std::string port = argv[2];
 int threads = atoi(argv[3]);
 int timeout = atoi(argv[4]);
 std::ifstream in{argv[1]};
 std::vector<std::string> domains;
 std::copy(std::istream_iterator<std::string>(in),
 std::istream_iterator<std::string>(), 
 std::back_inserter(domains));
 std::ofstream myfile{output_file};
 std::vector<std::future<std::string>> results;
 for (const auto &domain: domains) {
 results.push_back(std::async(isPortOpen, domain, port));
 }
 std::for_each(results.begin(), results.end(), 
 [&myfile](std::future<std::string>& f){myfile << f.get();});
 
 myfile.close();
}

That's the whole thing, and it can be compiled with:

g++ -Wall -Wextra -pedantic -std=c++11 portchek.cpp -o portchek -lpthread

Putting it all together

Here's how to do it:

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
#include <future>
#include <cstring>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
std::string isPortOpen(const std::string &domain, const std::string &port)
{
 addrinfo *result;
 addrinfo hints{}; 
 hints.ai_family = AF_UNSPEC; // either IPv4 or IPv6
 hints.ai_socktype = SOCK_STREAM; 
 char addressString[INET6_ADDRSTRLEN];
 const char *retval = nullptr;
 if (0 != getaddrinfo(domain.c_str(), port.c_str(), &hints, &result)) {
 return "";
 }
 for (addrinfo *addr = result; addr != nullptr; addr = addr->ai_next) {
 int handle = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
 if (handle == -1) {
 continue;
 }
 if (connect(handle, addr->ai_addr, addr->ai_addrlen) != -1) {
 switch(addr->ai_family) {
 case AF_INET:
 retval = inet_ntop(addr->ai_family, &(reinterpret_cast<sockaddr_in *>(addr->ai_addr)->sin_addr), addressString, INET6_ADDRSTRLEN);
 break;
 case AF_INET6:
 retval = inet_ntop(addr->ai_family, &(reinterpret_cast<sockaddr_in6 *>(addr->ai_addr)->sin6_addr), addressString, INET6_ADDRSTRLEN);
 break;
 default:
 // unknown family
 retval = nullptr;
 }
 close(handle);
 break;
 }
 }
 freeaddrinfo(result);
 return retval==nullptr ? "" : domain + ":" + retval + "\n";
}
int main(int argc, char *argv[]) {
 if (argc != 6) {
 std::cerr << "Usage: " << argv[0] << " domains.txt port threads timeout output.txt\n";
 std::exit(-1);
 }
 std::string domains_file = argv[1];
 std::string output_file = argv[5];
 std::string port = argv[2];
 int threads = atoi(argv[3]);
 int timeout = atoi(argv[4]);
 std::ifstream in{argv[1]};
 std::vector<std::string> domains;
 std::copy(std::istream_iterator<std::string>(in),
 std::istream_iterator<std::string>(), 
 std::back_inserter(domains));
 std::ofstream myfile{output_file};
 std::vector<std::future<std::string>> results;
 for (const auto &domain: domains) {
 results.push_back(std::async(isPortOpen, domain, port));
 }
 std::for_each(results.begin(), results.end(), 
 [&myfile](std::future<std::string>& f){myfile << f.get();});
 
 myfile.close();
}

That's the whole thing, and it can be compiled with:

g++ -Wall -Wextra -pedantic -std=c++11 portchek.cpp -o portchek -lpthread

added 5 characters in body
Source Link
Edward
  • 67.2k
  • 4
  • 120
  • 284
std::vector<std::future<std::string>> results;
for (const auto &domain: domains) {
 results.push_back(std::async(isPortOpen, domain, port));
}
std::for_each(results.begin(), results.end(), 
 [&myfile](std::future<std::string>& f){myfile << f.get() << '\n';});
 
std::vector<std::future<std::string>> results;
for (const auto &domain: domains) {
 results.push_back(std::async(isPortOpen, domain, port));
}
for_each(results.begin(), results.end(), 
 [&myfile](std::future<std::string>& f){myfile << f.get() << '\n';});
 
std::vector<std::future<std::string>> results;
for (const auto &domain: domains) {
 results.push_back(std::async(isPortOpen, domain, port));
}
std::for_each(results.begin(), results.end(), 
 [&myfile](std::future<std::string>& f){myfile << f.get() << '\n';});
 
Source Link
Edward
  • 67.2k
  • 4
  • 120
  • 284
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /