int Socket::Connect(const char *hostname, unsigned short port) { unsigned long host_addr = ResolveHostname(hostname); if (host_addr == INADDR_NONE) return -1; struct sockaddr_in server_addr; /* Construct the server address structure */ memset(&server_addr, 0, sizeof(server_addr)); /* Zero out structure */ server_addr.sin_family = AF_INET; /* Internet address family */ server_addr.sin_addr.s_addr = host_addr; /* Server IP address */ server_addr.sin_port = htons(port); /* Server port */ if (connect(sd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { return -1; } return 0; }
// Create a connection. bool Connect(ConnectionWrapper *Connection, std::string Hostname, int32_t Port) { #ifdef _WIN32 InitializeWinsock(); #endif // Resolve the hostname. auto AddressInfo = ResolveHostname(Connection->Type == eConnection::STREAMED, Hostname, Port); if (AddressInfo == nullptr) return false; // Disconnect from the previous connection if reused. if (Connection->Handle.Streamed.Connected) { Shutdown(Connection); Connection->Handle.Streamed.Connected = false; } // Create a new socket. if (Connection->Handle.Streamed.Socket == nullptr) Connection->Handle.Streamed.Socket = (void *)socket(AddressInfo->ai_family, AddressInfo->ai_socktype, IPPROTO_TCP); if (Connection->Handle.Streamed.Socket == nullptr) { freeaddrinfo(AddressInfo); return false; } // Set non-blocking mode on the socket. u_long Nonblocking = 1; #ifdef _WIN32 ioctlsocket((SOCKET)Connection->Handle.Streamed.Socket, FIONBIO, &Nonblocking); #else ioctl(Connection->Handle.Streamed.Socket, FIONBIO, &Nonblocking); #endif // Connect to the address. if (connect((SOCKET)Connection->Handle.Streamed.Socket, AddressInfo->ai_addr, AddressInfo->ai_addrlen) != 0) { #if _WIN32 if (WSAGetLastError() == WSAEWOULDBLOCK) #else if (errno == EINPROGRESS) #endif { // Poll until the connection completes or times out. auto Starttime = std::chrono::steady_clock::now(); timeval Timeout; fd_set WFDs; // Set timeout to 5 sec. Timeout.tv_sec = 5; Timeout.tv_usec = 0; // Set the file descriptors. FD_ZERO(&WFDs); FD_SET((SOCKET)Connection->Handle.Streamed.Socket, &WFDs); // Poll the connection. if (select((int)Connection->Handle.Streamed.Socket + 1, NULL, &WFDs, NULL, &Timeout) > 0 && FD_ISSET((SOCKET)Connection->Handle.Streamed.Socket, &WFDs)) { freeaddrinfo(AddressInfo); return true; } } else { freeaddrinfo(AddressInfo); return false; } } return true; }
void AsyncResolver::DoWork() { error_ = ResolveHostname(addr_.hostname().c_str(), addr_.family(), &addresses_); }