// only for dev int main(int argc, char *argv[]) { // call QStringList command; // for(int i=1; i<argc; i++) { // command.append(QString("%1").arg(argv[i])); // } command.append("ping"); command.append("udp"); command.append("rzv"); qDebug() << "Return: " << udp_ping(command) << endl; }
int main(int argc, char *argv[]) { char buff[BUFLEN], sysbuff[2*BUFLEN]; short * ptr; int i; int testMode; // Test mode (RTT/througput) int lossPackets; // Lost packet number long_int * s_rtime_usec; // Server process wall clock time long_int * s_utime_usec; // Server process time in user mode long_int * s_stime_usec; // Server process time in system mode double clientTP, serverTP; // client/server throughputs double lossRate; // Packet loss rate struct SYSInfo * sysinfo = NULL; // System (CPU/Interrupts) information struct SYSInfo * serverinfo = NULL; // Server's system information struct PROInfo * proinfo; // Process information struct timeval tv; // Timestamp double ts; /**************** At least given server name ***************************/ if ( argc > 1 && strcmp(argv[1], "--help")==0 ) { fprintf(stderr, help_description); fprintf(stderr, help_usage, DEFAULTPORT, DEFAULTDATAGRAM, DEFAULTSIZE, DEFAULTPORT, DEFAULTREPEAT, DEFAULTTIME); fprintf(stderr, help_example); return 0; } else if ( argc < 3 ) { print_usage(); return 1; } /********* Data initialization and parse the command line **************/ init_data(); parse_command(argc, argv, &testMode); /********* Just send data in case of UDP traffic generator *************/ if ( setting.udpGen ) { udp_traffic_generator(hostname, tcpsock.port, udpsock.sendBuf, setting.testTime, setting.throughput); return 0; } /******************** Check the write file option **********************/ if ( setting.writeOption ) { if ( (output = fopen(filename, "w")) == NULL ) { fprintf(stderr, "%s: Unable to write the file!\n", filename); setting.writeOption = 0; } } /*************** Allocate memory to hold CPU information ***************/ if ( setting.CPUoption ) { /** Two more items to hold the syslog of pre/post states of test ***/ if ( (sysinfo = (struct SYSInfo *)malloc((setting.repeat + 2) * sizeof(struct SYSInfo))) == NULL ) { perror("Failed to malloc."); exit(1); } if ( start_trace_system( &sysinfo[0]) == NOTOK ) { fprintf(stderr, "Failed to monitor system information.\n"); setting.CPUoption = 0; } else { sleep(1); stop_trace_system( &sysinfo[0] ); } } /*********************** TCP connection to server *********************/ if (client_tcp_connect(hostname, &tcpsock) == NOTOK) { fprintf(stderr, "%s : %d ", hostname, tcpsock.port); perror("Unable to establish TCP connection."); return 1; } /*************** Send parameters to server *****************************/ sprintf(buff, test_init_str, testMode, udpsock.tos, setting.CPUoption, server.sendBuf, server.recvBuf, udpsock.packetSize, udpsock.dataSize); if ( tcp_send_request(buff, strlen(buff), &tcpsock) == NOTOK ) { perror("TCP send parameters error."); return 1; } /************ Get server's UDP connection setting *********************/ if ( tcp_get_request(buff, &tcpsock) == NOTOK || sscanf(buff, server_setting_str, &udpsock.port, &server.tos, &setting.sCPUoption, &server.sendBuf, &server.recvBuf, &server.packetSize, &server.dataSize) != 7) { perror("Failed to get UDP connection information."); return 1; } /************ Initialization of UDP communication *********************/ if (client_udp_init(hostname, &udpsock) == NOTOK) { fprintf(stderr, "%s : %d ", hostname, udpsock.port); perror("Failed to establish the UDP connection."); return 1; } if ( gethostname(localhost, BUFLEN) < 0 ) { perror("gethostname."); strcpy(localhost, "Localhost"); } /************************* Allocate memory *****************************/ if ( (buffer = (char *) malloc ( udpsock.packetSize)) == NULL ){ fprintf(stderr, "Malloc error : %d\n", udpsock.packetSize); return 1; } /******* Randomize the buffer to prevent the possible compression ******/ srand(time(NULL)); for(ptr = (short *)buffer; ptr < (short *)(buffer+udpsock.packetSize); ptr += 2 ) *ptr = (short)rand(); /*** Allocate memory to store the client/server process information ****/ if ( (proinfo = (struct PROInfo *)malloc((setting.repeat)*sizeof(struct PROInfo))) == NULL || (s_rtime_usec = (long_int *)malloc((setting.repeat)*sizeof(long_int))) == NULL || (s_utime_usec = (long_int *)malloc((setting.repeat)*sizeof(long_int))) == NULL || (s_stime_usec = (long_int *)malloc((setting.repeat)*sizeof(long_int))) == NULL ) { perror("Failed to malloc."); exit(1); } #ifdef DEBUG fprintf(stderr, " DEBUG: Client connected to server on port: %d\n", udpsock.port); #endif /********************** Handle the interruption ************************/ signal(SIGINT, sig_handler); signal(SIGTSTP, sig_handler); /********************** RTT (latency test) *****************************/ if ( testMode == LATENCY ) { udp_ping(); print_ping_result(); return 0; } /************************ UDP throughput test **************************/ /** We need another container to hold server's system info if defined **/ if ( setting.sCPUoption ) { // Server also monitor the system resource if ( (serverinfo = (struct SYSInfo *)malloc((setting.repeat + 2) * sizeof(struct SYSInfo))) == NULL ) { perror("Failed to malloc."); exit(1); } bzero(buff, BUFLEN); if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK || string_to_sysinfo( &serverinfo[0], sysbuff, 2*BUFLEN) == NOTOK ) { perror("Failed to get server's initial system information."); exit (1); } } /******************** Print out the connection message *****************/ if ( setting.verbose ) { fprintf(stderr, "UDP throughput %s test\n%s (client) <--> %s (server)\n", setting.exponential ? "exponential" : "fixed packet size", localhost, hostname); fprintf(stderr, "UDP-port: %d UDP-send-buffer: %d UDP-recv-buffer: %d\n", udpsock.port, udpsock.sendBuf, udpsock.recvBuf); } /******************* Write test parameters to a file *******************/ if ( setting.writeOption ) { get_local_time(curtime, BUFLEN); fprintf(output, "# UDP communication test -- %s\n", curtime); fprintf(output, "# %s size %s stream test\n", setting.exponential ? "Exponential":"Fixed packet", setting.bidirection ? "bidirectional":"unidirectional"); fprintf(output, "# Hosts: %s (client) <--> %s (server)\n\n", localhost, hostname); fprintf(output, "# Client UDP socket buffer size (Bytes) -- SNDBUF: %d RCVBUF: %d\n", udpsock.sendBuf, udpsock.recvBuf ); fprintf(output, "# Server UDP socket buffer size (Bytes) -- SNDBUF: %d RCVBUF: %d\n", server.sendBuf, server.recvBuf); qos_type(&udpsock, buff); fprintf(output, "# Client IP TOS type: %s\n", buff); qos_type(&server, buff); fprintf(output, "# Server IP TOS type: %s\n", buff); fprintf(output, "# UDP datagram (packet) size (Bytes) -- Client: %d Server: %d\n", udpsock.packetSize, server.packetSize); if ( setting.exponential ) { // Exponential test fprintf(output, "# Test time (second): %f\n\n", setting.testTime); if ( !setting.bidirection ) { fprintf(output, "# Size Network Local Client Client Server Server Server ServerRecv\n"); fprintf(output, "# (Byte) (Mbps) (Mbps) SentPkg SentByte RecvPkg RecvByte LostPkg LossRate Timestamp\n"); } else { fprintf(output, "# Size Network Local Client Client Server Server Client Client Server Server ServerRecv\n"); fprintf(output, "# (Byte) (Mbps) (Mbps) SentPkg SentByte RecvPkg RecvByte RecvPkg RecvByte SentPkg SentByte LossRate Timestamp\n"); } } else { // Fixed packet size test fprintf(output, "# Data size of each read/write (Bytes) -- Client: %d Server: %d\n", udpsock.dataSize, server.dataSize); fprintf(output, "# Message size (Bytes): %lld\n", setting.messageSize); fprintf(output, "# Test time (Second): %f\n# Test repeat: %d\n\n", setting.testTime, setting.repeat); if ( ! setting.bidirection ) // One way unidirectional test fprintf(output, "# Network(Mbps) Local(Mbps) SentPkg(C) SentByte(C) RecvPkg(S) RecvByte(S) LostPkg LossRate Timestamp\n"); else { // bidirection test fprintf(output, "# Network Local Client Client Server Server Client Client Server Server Server\n"); fprintf(output, "# throughput throughput sent sent recv recv recv recv sent sent recv Timestamp\n"); fprintf(output, "# (Mbps) (Mbps) packet byte packet byte packet byte packet byte loss-rate\n"); } // bidriection test } // Fixed packet size test } // If write option /********************** Start UDP throughput test **********************/ for ( i = 0; i < setting.repeat; i++ ) { if ( setting.exponential ) { udpsock.dataSize = (1<<i); // Increase the packet size doubly if ( udpsock.dataSize > udpsock.packetSize ) // The last one udpsock.dataSize = udpsock.packetSize; } /**************** Inform server to start UDP test ******************/ sprintf(buff, test_start_str, udpsock.dataSize, 0); if ( tcp_send_request(buff, strlen(buff), &tcpsock) == NOTOK ) { perror("Failed to send request."); client_shutdown(); exit (1); } /*************** Start monitoring system information ***************/ if ( setting.CPUoption ) start_trace_system(&sysinfo[i+1]); start_trace_process(&proinfo[i]); /***************** Start UPD throughput test ***********************/ if ( setting.bidirection ) { if ( client_udp_bi_test (setting.messageSize, setting.testTime, &udpsock) == NOTOK && error != TIMEOUT && error != DISORDER ) { perror("UDP test error."); client_shutdown(); exit (1); } } else if ( client_udp_test (setting.messageSize, setting.testTime, &udpsock, setting.throughput) == NOTOK && error != TIMEOUT && error != DISORDER ) { perror("UDP test error."); client_shutdown(); exit (1); } stop_trace_process(&proinfo[i]); if ( setting.CPUoption ) { usleep(1000); stop_trace_system(&sysinfo[i+1]); } #ifdef DEBUG fprintf(stderr, " DEBUG: One trip test done, sent Bytes: %lld sent packets: %d\n", udpsock.sentBytes, udpsock.sentPackets); fprintf(stderr, " DEBUG: Waiting server's test result ...\n"); #endif /************* Get server's test result by TCP channel *************/ if ( tcp_get_request(buff, &tcpsock) == NOTOK ) { fprintf(stderr, "Get result error (TCP data channel).\n"); client_shutdown(); exit(1); } else if ( strncmp(buff, test_time_out_str, strlen(test_time_out_str)) == 0 ) { if ( setting.sCPUoption ) { if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK || string_to_sysinfo( &serverinfo[i+1], sysbuff, 2*BUFLEN) == NOTOK ) { perror("Failed to get server's system information."); exit (1); } } fprintf(stderr, "UDP key packets lost. Igore the result.\n"); if ( setting.writeOption ) fprintf (output, "#%d UDP key packets lost. Igore the result.\n", i+1); s_rtime_usec[i] = s_utime_usec[i] = s_stime_usec[i] = 0; continue; } else if ( sscanf(buff, server_result_str, &server.recvBytes, &server.recvPackets, &server.sentBytes, &server.sentPackets, &server.elapsedTime, &s_utime_usec[i], &s_stime_usec[i]) != 7 ) { fprintf(stderr, "Failed to parse server's result: %s\n", buff); client_shutdown(); exit(1); } s_rtime_usec[i] = server.elapsedTime; if ( setting.sCPUoption ) { if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK || string_to_sysinfo( &serverinfo[i+1], sysbuff, 2*BUFLEN) == NOTOK ) { perror("Failed to get server's system information."); exit (1); } } localTP.trial++; networkTP.trial++; if ( server.elapsedTime <= 0 ) { fprintf(stderr, "Wrong of server's elapsed time! Ignore the result: %s\n", buff); continue; } serverTP = (server.recvBytes+udpsock.recvBytes) * 8.0 / server.elapsedTime; // Network count if ( networkTP.min > serverTP ) networkTP.min = serverTP; if ( networkTP.max < serverTP ) networkTP.max = serverTP; networkTP.sum += serverTP; clientTP = (server.sentBytes+udpsock.sentBytes) * 8.0 / udpsock.elapsedTime; // local count proinfo[i].rtime_sec = udpsock.elapsedTime / 1000000; proinfo[i].rtime_usec = udpsock.elapsedTime % 1000000; /************* Keep the minimum and maximum throughputs ************/ if ( localTP.min > clientTP ) localTP.min = clientTP; if ( localTP.max < clientTP ) localTP.max = clientTP; localTP.sum += clientTP; /****** Compute the packet loss rate of client sending *************/ lossPackets = udpsock.sentPackets - server.recvPackets; lossRate = lossPackets * 1.0 / udpsock.sentPackets; /*********************** Print out test results ********************/ if ( setting.verbose ) { if ( setting.exponential ) fprintf(stderr, "Message size: %d\n", udpsock.dataSize); fprintf(stderr, "\n[Client] Sent-bytes: %lld Sent-packets: %d ", udpsock.sentBytes, udpsock.sentPackets); fprintf(stderr, "Recv-bytes: %lld Recv-Packets: %d\n", udpsock.recvBytes, udpsock.recvPackets); fprintf(stderr, "[Server] Recv-bytes: %lld Recv-Packets: %d ", server.recvBytes, server.recvPackets); fprintf(stderr, "Sent-bytes: %lld Sent-Packets: %d\n", server.sentBytes, server.sentPackets); fprintf(stderr, "Client-time(Sec.): %f Server-time(Sec.): %f\n", udpsock.elapsedTime/1000000.0, server.elapsedTime/1000000.0); fprintf(stderr, "Network-throughput(Mbps): %f Local-throughput: %f\n", serverTP, clientTP); fprintf(stderr, "Lost-packets (c->s): %d Loss-rate(c->s): %f\n\n", lossPackets, lossRate); } else fprintf(stderr, " (%d) Throughput: %f Loss-rate: %f\n", i+1, serverTP, lossRate); /*************** Store test results in the file ********************/ gettimeofday(&tv, NULL); ts = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; if ( setting.writeOption ) { if ( setting.exponential ) { // exponential throughput test if ( !setting.bidirection ) fprintf (output, "%-3d%6d%10.3f%10.3f%10d%12lld%10d%12lld%10d%10.3f%17.2f\n", i+1, udpsock.dataSize, serverTP, clientTP, udpsock.sentPackets, udpsock.sentBytes, server.recvPackets, server.recvBytes, lossPackets, lossRate, ts); else fprintf (output, "%-3d%6d%10.3f%10.3f%10d%12lld%10d%12lld%10d%12lld%10d%12lld%12.3f%17.2f\n", i+1, udpsock.dataSize, serverTP, clientTP, udpsock.sentPackets, udpsock.sentBytes, server.recvPackets, server.recvBytes, udpsock.recvPackets, udpsock.recvBytes, server.sentPackets, server.sentBytes, lossRate, ts); } else if ( !setting.bidirection ) // unidirectional throughput test fprintf (output, "%-3d%13.4f%12.4f%11d%12lld%11d%12lld%10d%10.3f%17.2f\n", i+1, serverTP, clientTP, udpsock.sentPackets, udpsock.sentBytes, server.recvPackets, server.recvBytes, lossPackets, lossRate, ts); else { // bidirectional throughput test fprintf(output, "%-3d%10.3f%11.3f%9d", i+1, serverTP, clientTP, udpsock.sentPackets); fprintf(output, "%12lld%9d%12lld", udpsock.sentBytes, server.recvPackets, server.recvBytes); fprintf(output, "%9d%12lld%9d", udpsock.recvPackets, udpsock.recvBytes, server.sentPackets); fprintf(output, "%12lld%9.3f%17.2f\n", server.sentBytes, lossRate, ts); } // bidriection test } // if write option } // for loop of repeat /********************** Inform server the end of the session ***********/ sprintf(buff, test_end_str); if ( tcp_send_request (buff, strlen(buff), &tcpsock) == NOTOK ) fprintf(stderr, "Close session error."); if ( setting.CPUoption ) { // record the post-test system info if ( start_trace_system( &sysinfo[setting.repeat+1] ) == NOTOK ) { perror("Failed to trace system in final state."); exit (1); } sleep(1); if ( stop_trace_system( &sysinfo[setting.repeat+1] ) == NOTOK ) { perror("Failed to trace system in final state."); exit (1); } if ( setting.sCPUoption ) { if ( tcp_get_request(sysbuff, &tcpsock) == NOTOK || string_to_sysinfo( &serverinfo[setting.repeat+1], sysbuff, 2*BUFLEN) == NOTOK ) { perror("Failed to get server's last syslog."); exit (1); } } } /***** Compute the average throughput for fixed-size message tests *****/ if ( !setting.exponential && setting.writeOption && localTP.trial > 2 ) { localTP.avg = localTP.sum/localTP.trial; networkTP.avg = networkTP.sum/localTP.trial; fprintf(output, "\n# Local Average: %10f Minimum: %10f Maximum: %10f\n", localTP.avg, localTP.min, localTP.max); fprintf(output, "# Network Average: %10f Minimum: %10f Maximum: %10f\n", networkTP.avg, networkTP.min, networkTP.max); } if ( setting.writeOption ) { fprintf(output, "\n# Process information for each test: \n\n"); fprintf(output, "# Client C-process C-process Server S-process S-process\n"); fprintf(output, "# Elapsed-time User-mode System-mode Elapsed-time User-mode System-mode\n"); fprintf(output, "# (Seconds) (Seconds) (Seconds) (Seconds) (Seconds) (Seconds)\n"); for ( i = 0; i < setting.repeat; i++ ) { fprintf(output, "#%-4d%11.2f%13.2f%12.2f%13.2f%13.2f%12.2f\n", i+1, (double)proinfo[i].rtime_sec + proinfo[i].rtime_usec/1000000.0, (double)proinfo[i].utime_sec + proinfo[i].utime_usec/1000000.0, (double)proinfo[i].stime_sec + proinfo[i].stime_usec/1000000.0, s_rtime_usec[i]/1000000.0, s_utime_usec[i]/1000000.0, s_stime_usec[i]/1000000.0); } fprintf(output, "\n"); fclose(output); fprintf(stderr, "Test done! The results are stored in file \"%s\"\n", filename); if ( setting.CPUoption ) { strcpy(buff, filename); strcat(buff, ".c_log"); if ( write_sys_info(sysinfo, setting.repeat+2, buff, curtime, localhost) == OK ) fprintf(stderr, "Local-syslog: \"%s\" ", buff); strcpy(buff, filename); strcat(buff, ".s_log"); if ( setting.sCPUoption && write_sys_info(serverinfo, setting.repeat+2, buff, curtime, hostname) == OK ) fprintf(stderr, "server-syslog: \"%s\"", buff); fprintf(stderr, "\n"); } if ( setting.plotOption && write_plot() == OK ) { fprintf(stderr, "Plot-file: \"%s\". ", plotname); fprintf(stderr, "Use \"gnuplot %s\" to plot the data\n", plotname); } fclose(output); } else fprintf(stderr, "Test done!\n"); /*************************** Close the connection **********************/ client_shutdown(); return 0; } // end of main function