00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "spocket_tester.h"
00021
00022 #include <basis/byte_array.h>
00023 #include <basis/istring.h>
00024 #include <loggers/file_logger.h>
00025 #include <data_struct/static_memory_gremlin.h>
00026 #include <sockets/address.h>
00027
00028 #include <stdio.h>
00029 #include <string.h>
00030
00031 HOOPLE_STARTUP_CODE;
00032
00033 #define LOG(s) program_wide_logger().log(s)
00034
00035 typedef byte ip_address_holder[4];
00036
00037
00038 bool parse_address(const istring &input, ip_address_holder &ip_address)
00039 {
00040 int index = 0;
00041 int current_byte = 0;
00042 const char *last_period = 0;
00043 bool got_digit = false;
00044 for (const char *address = input.s(); *address; address++) {
00045 if ( (*address <= '9') && (*address >= '0') ) {
00046 current_byte *= 10;
00047 current_byte += *address - '0';
00048 got_digit = true;
00049 } else if (*address == '.') {
00050 got_digit = false;
00051 if (last_period + 1 == address) {
00052 LOG("The IP address entry has an empty digit. Exiting.");
00053 return false;
00054 }
00055 last_period = address;
00056 if (current_byte > 255) {
00057 LOG("The IP address entry has an illegal byte. Exiting.");
00058 return false;
00059 }
00060 ip_address[index] = byte(current_byte);
00061 current_byte = 0;
00062 index++;
00063 if (index > 3) break;
00064
00065 } else {
00066 LOG("The IP address entry has illegal characters. Exiting.");
00067 return false;
00068 }
00069 }
00070
00071 if ( (index == 3) && got_digit) {
00072 if (current_byte > 255) {
00073 LOG("The IP address entry has an illegal byte. Exiting.");
00074 return false;
00075 }
00076 ip_address[index] = current_byte;
00077 } else if (index < 4) {
00078 LOG("The IP address entry is too short. Exiting.");
00079 return false;
00080 }
00081 return true;
00082 }
00083
00084 int main(int argc, char *argv[])
00085 {
00086 SET_DEFAULT_COMBO_LOGGER;
00087
00088 if (argc < 6) {
00089 LOG("\
00090 This program takes five command line arguments to begin operation.\n\
00091 These arguments (in order) are:\n\
00092 \tIP address\t\tIn the form w.x.y.z\n\
00093 \tPort number\t\tAs a short integer\n\
00094 \tTester role\t\tEither \"client\" or \"server\"\n\
00095 \tSend size\t\tThe size of the data to exchange.\n\
00096 \tSend count\t\tThe number of \"packets\" to exchange.\n\
00097 Note: it is expected that the client and server have equal send sizes;\n\
00098 this allows the receiver to know when it's gotten all the data that's\n\
00099 expected during a cycle.");
00100 return 1;
00101 }
00102
00103 ip_address_holder ip_address;
00104 parse_address(argv[1], ip_address);
00105
00106 LOG(isprintf("\tParsed an IP address: \"%d.%d.%d.%d\".",
00107 (int)ip_address[0], (int)ip_address[1], (int)ip_address[2],
00108 (int)ip_address[3]));
00109
00110
00111 int port = 0;
00112 if (sscanf(argv[2], "%d", &port) < 1) {
00113 LOG("The port entry is malformed. Exiting.");
00114 return 3;
00115 }
00116 LOG(isprintf("\tGot a port of %d.", port));
00117
00118
00119 bool client;
00120 istring arg3 = argv[3];
00121 arg3.to_lower();
00122 if (arg3 == "client") client = true;
00123 else if (arg3 == "server") client = false;
00124 else {
00125 LOG("The tester role (client/server) is malformed. Exiting.");
00126 return 4;
00127 }
00128 if (client) LOG("\tTester role is \"client\".");
00129 else LOG("\tTester role is \"server\".");
00130
00131
00132 int send_size = 0;
00133 if (sscanf(argv[4], "%d", &send_size) < 1) {
00134 LOG("The send size entry is malformed. Exiting.");
00135 return 5;
00136 }
00137 LOG(isprintf("\tGot a send size of %d.", send_size));
00138
00139
00140 int send_count = 0;
00141 if (sscanf(argv[5], "%d", &send_count) < 1) {
00142 LOG("The send count entry is malformed. Exiting.");
00143 return 5;
00144 }
00145 LOG(isprintf("\tGot a send count of %d.", send_count));
00146
00147
00148 internet_address to_pass(byte_array(4, ip_address), "", port);
00149
00150
00151 spocket_tester tester(to_pass);
00152
00153
00154 bool outcome;
00155 if (client)
00156 outcome = tester.connect();
00157 else
00158 outcome = tester.accept();
00159 if (!outcome) {
00160 const char *action = client? "connect" : "accept";
00161 LOG(istring("Failed to ") + action + " on the tester.");
00162 return 10;
00163 }
00164
00165
00166 testing_statistics stats;
00167 outcome = tester.perform_test(send_size, send_count * 2, stats);
00168
00169 if (!outcome) {
00170 LOG("Failed out of send_data; maybe other side terminated.");
00171 }
00172
00173 stats.total_runs /= 2;
00174
00175 if (!stats.total_runs)
00176 stats.total_runs = 1;
00177
00178
00179 LOG(isprintf("Report for %d completed test cycles.", stats.total_runs));
00180 LOG("");
00181 LOG("\t\tsend stats\t\treceive stats");
00182 LOG("\t\t----------\t\t-------------");
00183 LOG(isprintf("bytes\t\t%d\t\t\t%d", stats.bytes_sent,
00184 stats.bytes_received));
00185 LOG(isprintf("time\t\t%d\t\t\t%d", stats.send_time, stats.receive_time));
00186 LOG(isprintf("avg. bytes\t%d\t\t\t%d", stats.bytes_sent
00187 / stats.total_runs / 2, stats.bytes_received / stats.total_runs / 2));
00188 LOG("");
00189 LOG(isprintf("round trip time: %d ms", stats.round_trip_time));
00190
00191 double bandwidth = double(stats.bytes_sent + stats.bytes_received)
00192 / stats.round_trip_time / 1024.0 * 1000.0;
00193 LOG(isprintf("bandwidth overall: %f K/s", bandwidth));
00194
00195 return 0;
00196 }
00197