1 //==========================================================================
5 // Simple TCP throughput test - sink component
6 // * CAUTION: host, i.e. non eCos, only *
8 //==========================================================================
9 //####BSDCOPYRIGHTBEGIN####
11 // -------------------------------------------
13 // Portions of this software may have been derived from OpenBSD or other sources,
14 // and are covered by the appropriate copyright disclaimers included herein.
16 // -------------------------------------------
18 //####BSDCOPYRIGHTEND####
19 //==========================================================================
20 //#####DESCRIPTIONBEGIN####
23 // Contributors: gthomas
26 // Description: This is the middle part of a three part test. The idea is
27 // to test the throughput of box in a configuration like this:
29 // +------+ port +----+ port +----+
30 // |SOURCE|=========>|ECHO|============>|SINK|
31 // +------+ 9990 +----+ 9991 +----+
34 //####DESCRIPTIONEND####
36 //==========================================================================
38 // Network throughput test code
45 #include <sys/param.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/in.h>
54 #include <netinet/ip.h>
55 #include <netinet/ip_icmp.h>
59 #define SOURCE_PORT 9990
60 #define SINK_PORT 9991
73 #define MAX_BUF 32 * 8192
74 static unsigned char data_buf[MAX_BUF];
84 show_results(struct timeval *start, struct timeval *end,
85 int nbufs, int buflen)
87 struct timeval tot_time;
88 long tot_bytes = nbufs * buflen;
89 double real_time, thru;
90 timersub(end, start, &tot_time);
91 printf("SINK complete - %d bufs of %d bytes in %ld.%02ld seconds",
93 tot_time.tv_sec, tot_time.tv_usec / 10000);
94 real_time = tot_time.tv_sec + ((tot_time.tv_usec / 10000) * .01);
95 // Compute bytes / second (rounded up)
96 thru = tot_bytes / real_time;
97 // Convert to Mb / second
98 printf(" - %.2f KB/S", thru / 1024.0);
99 printf(" - %.4f Mbit/S (M = 10^6)", thru * 8.0 / 1000000.0);
104 do_read(int s, unsigned char *buf, int len)
106 int total, slen, rlen;
109 while (total < len) {
110 slen = read(s, buf, rlen);
113 printf("Error after reading %d bytes\n", total);
125 do_write(int s, unsigned char *buf, int len)
127 int total, slen, rlen;
130 while (total < len) {
131 slen = write(s, buf, rlen);
134 printf("Error after writing %d bytes\n", total);
146 sink_test(char *echo_node)
149 struct sockaddr_in slave, local;
152 struct hostent *host;
153 struct test_params params, nparams;
154 struct test_status status, nstatus;
155 struct timeval start_time, end_time;
158 printf("Start TCP test - SINK mode to %s\n", echo_node);
160 host = gethostbyname(echo_node);
161 if (host == (struct hostent *)NULL) {
162 pexit("gethostbyname");
165 memset(&slave, 0, sizeof(slave));
166 slave.sin_family = AF_INET;
168 slave.sin_len = sizeof(slave);
170 slave.sin_port = htons(SINK_PORT);
171 memcpy(&slave.sin_addr.s_addr, host->h_addr, host->h_length);
173 s_sink = socket(AF_INET, SOCK_STREAM, 0);
175 pexit("stream socket");
177 if (setsockopt(s_sink, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
178 pexit("setsockopt /sink/ SO_REUSEADDR");
180 memset(&local, 0, sizeof(local));
181 local.sin_family = AF_INET;
183 local.sin_len = sizeof(local);
185 local.sin_port = INADDR_ANY;
186 local.sin_addr.s_addr = INADDR_ANY;
187 if(bind(s_sink, (struct sockaddr *) &local, sizeof(local)) < 0) {
188 pexit("bind /sink/ error");
191 if (connect(s_sink, (struct sockaddr *)&slave, sizeof(slave)) < 0) {
192 pexit("Can't connect to target");
195 // Get testing paramters from middleman
196 if (do_read(s_sink, (unsigned char *)&nparams, sizeof(nparams))
197 != sizeof(nparams)) {
198 pexit("Can't read initialization parameters");
201 params.nbufs = ntohl(nparams.nbufs);
202 params.bufsize = ntohl(nparams.bufsize);
203 params.load = ntohl(nparams.load);
205 printf("Using %ld buffers of %ld bytes each\n", params.nbufs, params.bufsize);
208 gettimeofday(&start_time, 0);
209 for (i = 0; i < params.nbufs; i++) {
210 if ((len = do_read(s_sink, data_buf, params.bufsize)) != params.bufsize) {
211 printf("Error reading buffer #%d:", i+1);
213 perror("can't read data");
215 printf(" short data, only read %d bytes\n", len);
219 gettimeofday(&end_time, 0);
220 show_results(&start_time, &end_time, params.nbufs, params.bufsize);
222 // Tell the middleman
224 nstatus.ok = htonl(status.ok);
226 if (do_write(s_sink, (unsigned char *)&nstatus, sizeof(nstatus))
227 != sizeof(nstatus)) {
228 pexit("Can't send ACK to 'echo' host");
233 main(int argc, char *argv[])