int do_communicate (const struct sockaddr_in *sock_addr_p, socklen_t addrlen, enum comm_complexity how) { int result = 0; char *buf; static const size_t buf_size = 10 * 1024; buf = malloc (buf_size + 1); /* Extra byte for null-termination */ if (NULL == buf) { result = 99; fprintf (stderr, "Error allocating memory for buffer.\n"); } else { SYS_socket clnt_s; if (!sock_addr_p) return 99; clnt_s = socket (AF_INET, SOCK_STREAM, 0); if (SYS_INVALID_SOCKET == clnt_s) { fprintf (stderr, "Can't create socket: %u\n", (unsigned)SYS_sock_errno); result = 99; } else { char *str_addr; printf ("\nTrying communication sequence with server_part %s.\n", str_complexity (how)); str_addr = inet_ntoa (sock_addr_p->sin_addr); if (!str_addr) str_addr = "server_part"; printf ("Connecting to %s...\n", str_addr); if (connect (clnt_s, (const struct sockaddr*)sock_addr_p, addrlen) < 0) { fprintf (stderr, "Failed to connect: %u\n", (unsigned)SYS_sock_errno); result = 99; } else { static const char data1[] = "FIRST PING\n"; printf ("Connected. Sending \"FIRST PING\".\n"); if (!send_str (clnt_s, data1, sizeof (data1) - 1)) { result = 1; fprintf (stderr, "Error sending data.\n"); } else { char *rcv_ptr; char *processed_ptr; const char *nl_ptr; rcv_ptr = buf; processed_ptr = buf; printf ("Sent. Waiting for receive \"FIRST PONG\".\n"); nl_ptr = recv_line (clnt_s, &rcv_ptr, buf_size - (rcv_ptr - buf)); if (!nl_ptr) { result = 1; fprintf (stderr, "Error receiving \"FIRST PONG\".\n"); } else { rcv_ptr[0] = 0; /* Null-terminate for safety */ printf ("Received: %*.*s\n", (int)(nl_ptr - processed_ptr), (int)(nl_ptr - processed_ptr), processed_ptr); if (!cmp_to_lower (processed_ptr, nl_ptr - processed_ptr, "first pong")) { result = 1; fprintf (stderr, "Expected marker not found in received data.\n"); } else { static const char data2[] = "SECOND PING\n"; processed_ptr = rcv_ptr; printf ("Sending \"SECOND PING\".\n"); if (!send_str (clnt_s, data2, sizeof (data2) - 1)) { result = 1; fprintf (stderr, "Error sending data.\n"); } else { printf ("Sent.\n"); if (how == COMM_DELAY || how == COMM_DELAY_ADD_DATA) { printf ("Idling for delayed response receive...\n"); local_sleep (1500); } if (how == COMM_ADD_DATA || how == COMM_DELAY_ADD_DATA || how == COMM_ADD_DATA_TCPNDL || how == COMM_ADD_DATA_DELAY) { static const char data_ign[] = "Additional data to be ignored.\n"; int on_val, off_val; on_val = 1; off_val = 0; if (how == COMM_ADD_DATA_TCPNDL && 0 != setsockopt (clnt_s, IPPROTO_TCP, TCP_NODELAY, (void*)&on_val, sizeof (on_val))) { result = 99; fprintf(stderr,"Can't set TCP_ONDELAY option: %d.\n", (unsigned)SYS_sock_errno); } printf ("Sending additional ignorable data.\n"); if (!send_str (clnt_s, data_ign, sizeof (data_ign) - 1)) { printf ("Sending data failed.\n"); } else { printf ("Sent.\n"); } } if (how == COMM_ADD_DATA_DELAY) { printf ("Idling after additional sending for delayed response receive...\n"); local_sleep (1500); } printf ("Waiting for \"SECOND PONG\".\n"); SYS_reset_sock_errno (); nl_ptr = recv_line (clnt_s, &rcv_ptr, buf_size - (rcv_ptr - buf)); if (!nl_ptr) { int err = SYS_sock_errno; result = 1; fprintf (stderr, "Error receiving \"SECOND PONG\".\n"); if (SYS_ECONNABORTED == err || SYS_ECONNRESET == err) fprintf (stderr, "Looks like any received data was lost in system on this host after this system detected that connection was closed by remote side.\n"); } else { rcv_ptr[0] = 0; /* Null-terminate for safety */ printf ("Received: %*.*s\n", (int)(nl_ptr - processed_ptr), (int)(nl_ptr - processed_ptr), processed_ptr); if (!cmp_to_lower (processed_ptr, nl_ptr - processed_ptr, "second pong")) { result = 1; fprintf (stderr, "Expected marker not found in received data.\n"); } else { printf ("Sequence completed.\n"); } } } } } } } } printf ("Closing connection.\n"); SYS_socket_close_ (clnt_s); } if (result) fprintf (stderr, "Completed with some error.\n"); else printf ("Completed without errors.\n"); return result; }
int main (int argc, char *const *argv) { int i; time_t start_t, end_t; int result = 0; MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *test_func)(void* data); #ifdef MHD_WINSOCK_SOCKETS WORD ver_req; WSADATA wsa_data; int err; #endif /* MHD_WINSOCK_SOCKETS */ bool test_poll; test_poll = has_in_name(argv[0], "_poll"); if (!test_poll) test_func = &select_thread; else { #ifndef HAVE_POLL return 77; #else /* ! HAVE_POLL */ test_func = &poll_thread; #endif /* ! HAVE_POLL */ } #ifdef MHD_WINSOCK_SOCKETS ver_req = MAKEWORD(2, 2); err = WSAStartup(ver_req, &wsa_data); if (err != 0 || MAKEWORD(2, 2) != wsa_data.wVersion) { printf("WSAStartup() failed\n"); WSACleanup(); return 99; } #endif /* MHD_WINSOCK_SOCKETS */ /* try several times to ensure that accidental incoming connection * didn't interfere with test results */ for (i = 0; i < 5 && result == 0; i++) { MHD_thread_handle_ sel_thrd; /* fprintf(stdout, "Creating, binding and listening socket...\n"); */ MHD_socket listen_socket = start_socket_listen (AF_INET); if (MHD_INVALID_SOCKET == listen_socket) return 99; check_err = !0; /* fprintf (stdout, "Starting select() thread...\n"); */ #if defined(MHD_USE_POSIX_THREADS) if (0 != pthread_create (&sel_thrd, NULL, test_func, &listen_socket)) { MHD_socket_close_chk_ (listen_socket); fprintf (stderr, "Can't start thread\n"); return 99; } #elif defined(MHD_USE_W32_THREADS) sel_thrd = (HANDLE)_beginthreadex (NULL, 0, test_func, &listen_socket, 0, NULL); if (0 == (sel_thrd)) { MHD_socket_close_chk_ (listen_socket); fprintf (stderr, "Can't start select() thread\n"); return 99; } #else #error No threading lib available #endif /* fprintf (stdout, "Waiting...\n"); */ local_sleep(1); /* make sure that select() is started */ /* fprintf (stdout, "Shutting down socket...\n"); */ start_t = time (NULL); shutdown (listen_socket, SHUT_RDWR); /* fprintf (stdout, "Waiting for thread to finish...\n"); */ if (!MHD_join_thread_(sel_thrd)) { MHD_socket_close_chk_(listen_socket); fprintf (stderr, "Can't join select() thread\n"); return 99; } if (check_err) { MHD_socket_close_chk_(listen_socket); fprintf (stderr, "Error in waiting thread\n"); return 99; } end_t = time (NULL); /* fprintf (stdout, "Thread finished.\n"); */ MHD_socket_close_chk_(listen_socket); if (start_t == (time_t)-1 || end_t == (time_t)-1) { MHD_socket_close_chk_(listen_socket); fprintf (stderr, "Can't get current time\n"); return 99; } if (end_t - start_t > 3) result++; } #ifdef MHD_WINSOCK_SOCKETS WSACleanup(); #endif /* MHD_WINSOCK_SOCKETS */ return result; }