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