/* WARNING! Don't just blindly copy code -- check to see if you need to make * any tweaks to do exactly what you want it to. * You should also NOT assume that this sample code has perfect style. */ #include #include #include #include #include #include #include #include #include #include #include void Usage(char* progname); bool LookupName(char* name, unsigned short port, struct sockaddr_storage* ret_addr, size_t* ret_addrlen); int main(int argc, char** argv) { if (argc != 3) { Usage(argv[0]); } unsigned short port = 0; if (sscanf(argv[2], "%hu", &port) != 1) { Usage(argv[0]); } // Get an appropriate sockaddr structure. struct sockaddr_storage addr; size_t addrlen; if (!LookupName(argv[1], port, &addr, &addrlen)) { Usage(argv[0]); } // Create the socket. int socket_fd = socket(addr.ss_family, SOCK_STREAM, 0); if (socket_fd == -1) { std::cerr << "socket() failed: " << strerror(errno) << std::endl; return EXIT_FAILURE; } // Connect the socket to the remote host. int res = connect(socket_fd, reinterpret_cast(&addr), addrlen); if (res == -1) { std::cerr << "connect() failed: " << strerror(errno) << std::endl; } // Clean up. close(socket_fd); return EXIT_SUCCESS; } void Usage(char* progname) { std::cerr << "usage: " << progname << " hostname port" << std::endl; exit(EXIT_FAILURE); } bool LookupName(char* name, unsigned short port, struct sockaddr_storage* ret_addr, size_t* ret_addrlen) { struct addrinfo hints, *results; int retval; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; // Do the lookup by invoking getaddrinfo(). if ((retval = getaddrinfo(name, nullptr, &hints, &results)) != 0) { std::cerr << "getaddrinfo failed: "; std::cerr << gai_strerror(retval) << std::endl; return false; } // Set the port in the first result. if (results->ai_family == AF_INET) { struct sockaddr_in* v4addr = reinterpret_cast(results->ai_addr); v4addr->sin_port = htons(port); } else if (results->ai_family == AF_INET6) { struct sockaddr_in6* v6addr = reinterpret_cast(results->ai_addr); v6addr->sin6_port = htons(port); } else { std::cerr << "getaddrinfo failed to provide an IPv4 or IPv6 address"; std::cerr << std::endl; freeaddrinfo(results); return false; } // Return the first result. assert(results != nullptr); memcpy(ret_addr, results->ai_addr, results->ai_addrlen); *ret_addrlen = results->ai_addrlen; // Clean up. freeaddrinfo(results); return true; }