static void * client (void *arg) { ACE_INET_Addr *remote_addr = (ACE_INET_Addr *) arg; ACE_INET_Addr server_addr (remote_addr->get_port_number (), ACE_IPV6_LOCALHOST); ACE_SOCK_Stream cli_stream; ACE_SOCK_Connector con; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) starting non-blocking connect\n"))); // Initiate timed, non-blocking connection with server. // Attempt a non-blocking connect to the server. if (con.connect (cli_stream, server_addr, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) { if (errno != EWOULDBLOCK) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("connection failed"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) starting timed connect\n"))); // Check if non-blocking connection is in progress, // and wait up to ACE_DEFAULT_TIMEOUT seconds for it to complete. ACE_Time_Value tv (ACE_DEFAULT_TIMEOUT); if (con.complete (cli_stream, &server_addr, &tv) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("connection failed")), 0); else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) connected to %C\n"), server_addr.get_host_name ())); } if (cli_stream.disable (ACE_NONBLOCK) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("disable"))); // Send data to server (correctly handles "incomplete writes"). for (const char *c = ACE_ALPHABET; *c != '\0'; c++) if (cli_stream.send_n (c, 1) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("send_n"))); // Explicitly close the writer-side of the connection. if (cli_stream.close_writer () == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("close_writer"))); char buf[1]; // Wait for handshake with server. if (cli_stream.recv_n (buf, 1) != 1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("recv_n"))); // Close the connection completely. if (cli_stream.close () == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("close"))); return 0; }
static int succeed_nonblocking (void) { ACE_TCHAR test_host[MAXHOSTNAMELEN], test_addr[MAXHOSTNAMELEN + 8]; int status; ACE_INET_Addr echo_server; ACE_SOCK_Connector con; ACE_SOCK_Stream sock; ACE_Time_Value nonblock (0, 0); u_short test_port = 7; // Echo find_another_host (test_host); if (ACE_OS::strcmp (ACE_TEXT ("localhost"), test_host) == 0) { #if defined (ACE_WIN32) test_port = 80; // Echo not available on Win32; try web server #endif /* ACE_WIN32 */ } if (echo_server.set (test_port, test_host) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Host lookup for %s %p\n"), test_host, ACE_TEXT ("failed"))); return -1; } echo_server.addr_to_string (test_addr, MAXHOSTNAMELEN + 8); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing to host \"%s\", port %d (%s)\n"), test_host, test_port, test_addr)); status = con.connect (sock, echo_server, &nonblock); // Need to test the call to 'complete' really. if (status == 0 || (status == -1 && errno != EWOULDBLOCK)) { ACE_DEBUG((LM_WARNING, ACE_TEXT ("Immediate success/fail; test not completed\n"))); status = 0; } else { if (sock.get_handle () != ACE_INVALID_HANDLE) { status = con.complete (sock); } if (status == -1) { // Reset the status _before_ doing the printout, in case the // printout overwrites errno. if (errno == ECONNREFUSED) { status = 0; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Should succeed, but refused: ok\n"))); } else { ACE_ERROR ((LM_ERROR, ACE_TEXT("Errno <%d>: %p\n"), ACE_ERRNO_GET, ACE_TEXT("connect should succeed, but"))); } } else ACE_DEBUG((LM_DEBUG, ACE_TEXT("Connect which should succeed, did\n"))); } // Just in case. sock.close (); return status; }
static int fail_no_listener_nonblocking (void) { ACE_TCHAR test_host[MAXHOSTNAMELEN], test_addr[MAXHOSTNAMELEN + 8]; int status; ACE_INET_Addr nobody_home; ACE_SOCK_Connector con; ACE_SOCK_Stream sock; ACE_Time_Value nonblock (0, 0); find_another_host (test_host); if (nobody_home.set ((u_short) 42000, test_host) == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Host lookup for %s %p\n"), test_host, ACE_TEXT ("failed"))); return -1; } nobody_home.addr_to_string (test_addr, MAXHOSTNAMELEN + 8); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing to host \"%s\" (%s)\n"), test_host, test_addr)); status = con.connect (sock, nobody_home, &nonblock); // Need a port that will fail. if (status == 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Connect which should fail didn't\n"))); status = -1; } // On some systems, a failed connect to localhost will return // ECONNREFUSED or ENETUNREACH directly, instead of // EWOULDBLOCK. That is also fine. else if (errno == EWOULDBLOCK || errno == ECONNREFUSED || errno == ENETUNREACH) { if (sock.get_handle () != ACE_INVALID_HANDLE) status = con.complete (sock); if (status != -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Connect which should fail didn't\n"))); status = -1; } else { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%p\n"), ACE_TEXT ("Proper fail"))); status = 0; } } else { ACE_DEBUG ((LM_WARNING, ACE_TEXT ("Test not executed fully; ") ACE_TEXT ("expected EWOULDBLOCK, %p (%d)\n"), ACE_TEXT ("not"), ACE_ERRNO_GET)); status = -1; } // Just in case. sock.close (); return status; }