| 1 | /*
|
|---|
| 2 | * T T C P . C
|
|---|
| 3 | *
|
|---|
| 4 | * Test TCP connection. Makes a connection on port 5010
|
|---|
| 5 | * and transfers fabricated buffers or data copied from stdin.
|
|---|
| 6 | *
|
|---|
| 7 | * Usable on 4.2, 4.3, and 4.1a systems by defining one of
|
|---|
| 8 | * BSD42 BSD43 (BSD41a)
|
|---|
| 9 | * Machines using System V with BSD sockets should define SYSV.
|
|---|
| 10 | *
|
|---|
| 11 | * Modified for operation under 4.2BSD, 18 Dec 84
|
|---|
| 12 | * T.C. Slattery, USNA
|
|---|
| 13 | * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85.
|
|---|
| 14 | * Modified in 1989 at Silicon Graphics, Inc.
|
|---|
| 15 | * catch SIGPIPE to be able to print stats when receiver has died
|
|---|
| 16 | * for tcp, don't look for sentinel during reads to allow small transfers
|
|---|
| 17 | * increased default buffer size to 8K, nbuf to 2K to transfer 16MB
|
|---|
| 18 | * moved default port to 5001, beyond IPPORT_USERRESERVED
|
|---|
| 19 | * make sinkmode default because it is more popular,
|
|---|
| 20 | * -s now means don't sink/source
|
|---|
| 21 | * count number of read/write system calls to see effects of
|
|---|
| 22 | * blocking from full socket buffers
|
|---|
| 23 | * for tcp, -D option turns off buffered writes (sets TCP_NODELAY sockopt)
|
|---|
| 24 | * buffer alignment options, -A and -O
|
|---|
| 25 | * print stats in a format that's a bit easier to use with grep & awk
|
|---|
| 26 | * for SYSV, mimic BSD routines to use most of the existing timing code
|
|---|
| 27 | * Modified by Steve Miller of the University of Maryland, College Park
|
|---|
| 28 | * -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF)
|
|---|
| 29 | * Modified Sept. 1989 at Silicon Graphics, Inc.
|
|---|
| 30 | * restored -s sense at request of tcs@brl
|
|---|
| 31 | * Modified Oct. 1991 at Silicon Graphics, Inc.
|
|---|
| 32 | * use getopt(3) for option processing, add -f and -T options.
|
|---|
| 33 | * SGI IRIX 3.3 and 4.0 releases don't need #define SYSV.
|
|---|
| 34 | *
|
|---|
| 35 | * Modified --> Nov 1996 at CERN (Daniel DAVIDS)
|
|---|
| 36 | * printout of the Socket-Buffer-Sizes
|
|---|
| 37 | * configured for HP-UX 9000 OS
|
|---|
| 38 | * configured for Windows NT OS
|
|---|
| 39 | * Modified Dec 1996 at CERN (Jacques ROCHEZ)
|
|---|
| 40 | * severe cleanup
|
|---|
| 41 | * addaptation to the gcc compiler (ANSI)
|
|---|
| 42 | * configured for Lynx OS
|
|---|
| 43 | * automatic format for the rate display (G/M/K/)bytes/sec
|
|---|
| 44 | * added log (L) and more help (h) options.
|
|---|
| 45 | * Modified May 1997 at CERN (Jacques ROCHEZ)
|
|---|
| 46 | * removed the mes() function following err() function.
|
|---|
| 47 | * changed the default port to 5010
|
|---|
| 48 | * Modified jul 1997 at CERN (Jacques ROCHEZ)
|
|---|
| 49 | * adapted the timing calculation in microseconds
|
|---|
| 50 | * addapted the code for Vsisual C++ under NT4.0
|
|---|
| 51 | * Modified aug 1997 at CERN (Jacques ROCHEZ)
|
|---|
| 52 | * initialise to 0 the variables nbytes, numcalls
|
|---|
| 53 | * moved the buffer pre-load outside the measured timed area
|
|---|
| 54 | * Distribution Status -
|
|---|
| 55 | * Public Domain. Distribution Unlimited.
|
|---|
| 56 | * Modified jun 1998 at Epigram
|
|---|
| 57 | * - print hash marks to indicate prograss on transmitting side
|
|---|
| 58 | * - sleep between bursts of buffers
|
|---|
| 59 | * - set number of buffers/burst
|
|---|
| 60 | * Modified jul 1998 at Epigram
|
|---|
| 61 | * - send random size buffers
|
|---|
| 62 | * Modified jan 1999 at Epigram (WES)
|
|---|
| 63 | * - added start and end patterns to UDP start and end packets
|
|---|
| 64 | * - added handling of missed start, end, or data packets for UDP tests
|
|---|
| 65 | */
|
|---|
| 66 | #ifndef lint
|
|---|
| 67 | static char RCSid[] = "ttcp.c $- CERN Revision: 3.8 (dev level) -$";
|
|---|
| 68 | #endif
|
|---|
| 69 |
|
|---|
| 70 | static char VersDate[] = "Epigram 15-jul-98";
|
|---|
| 71 |
|
|---|
| 72 | /* system dependent setting
|
|---|
| 73 | * ------------------------
|
|---|
| 74 | * uname -a,gcc -v a.c are the tools used
|
|---|
| 75 | *
|
|---|
| 76 | * Platform/OS #define MACRO predefined
|
|---|
| 77 | * ----------- ------- ---------------------------------------------------
|
|---|
| 78 | * SunOS OS BSD43 __unix__ __sun__ __sparc__
|
|---|
| 79 | * SUN Solaris SYSV __unix__ __sun__ __sparc__ __svr4__
|
|---|
| 80 | * SGI-IRIX < 3.3 SYSV set as #define sgi
|
|---|
| 81 | * HP-UX 9000 SYSV __unix__ __hpux__ __hp9k8__
|
|---|
| 82 | * OSF/1 V3.2 SYSV __unix__ __osf__ __alpha__
|
|---|
| 83 | * OSF/1 V4.0 SYSV __unix__ __osf__ __alpha__ _CFE
|
|---|
| 84 | * LynxOS SYSV __unix__ __lynx__ __powerpc__
|
|---|
| 85 | * Windows NT SYSV __WINNT__ __i386__ __M_COFF__
|
|---|
| 86 | * AIX SYSV _AIX _AIX32 _POWER _IBMR2 _ARCH_PWR
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 | * Micosoft Visual C++ compiler under WindowNT 4.0
|
|---|
| 90 | * Windows NT _WINDOWS WIN32
|
|---|
| 91 |
|
|---|
| 92 | * Unix BSD 41a BSD41a
|
|---|
| 93 | * 42 BSD42
|
|---|
| 94 | * 43 BSD43
|
|---|
| 95 |
|
|---|
| 96 | * Machines using System V with BSD sockets should define SYSV.
|
|---|
| 97 | *
|
|---|
| 98 | * Compiler commands
|
|---|
| 99 | * -----------------
|
|---|
| 100 | * LynxOS : gcc -c ttcp.c -o ttcp.o | gcc -o ttcp -O ttcp.o -lnetinet -lc_p -lc
|
|---|
| 101 | */
|
|---|
| 102 |
|
|---|
| 103 | /* -------------attempt to set an automatic UNIX OS family detection -------*/
|
|---|
| 104 |
|
|---|
| 105 | #if defined(__hp9k8__) || defined(__osf__) || defined(__srv4__)
|
|---|
| 106 | #define SYSV
|
|---|
| 107 | #endif
|
|---|
| 108 | #if defined(__lynx__)
|
|---|
| 109 | #define SYSV
|
|---|
| 110 | #endif
|
|---|
| 111 | /* for solaris (__srv4__) the parameters SYSV is already set */
|
|---|
| 112 |
|
|---|
| 113 | /* version A.09.01 'key words' differs from A.09.05 A */
|
|---|
| 114 | #if defined(__hpux)
|
|---|
| 115 | #define __hpux__
|
|---|
| 116 | #endif
|
|---|
| 117 |
|
|---|
| 118 | #if defined(__sun__)&&!defined(__srv4__)
|
|---|
| 119 | #define BSD43 /* changed by BSD42 if necessary */
|
|---|
| 120 | #endif
|
|---|
| 121 |
|
|---|
| 122 | #if defined(_WIN32) /* Window NT 4.0 compiled with VisualC++ 4 */
|
|---|
| 123 | #define __NTVIS__
|
|---|
| 124 | #define SYSV
|
|---|
| 125 | #endif
|
|---|
| 126 |
|
|---|
| 127 | #if defined(__FreeBSD__)
|
|---|
| 128 | #define BSD43
|
|---|
| 129 | #endif
|
|---|
| 130 |
|
|---|
| 131 | #if defined(__linux__)
|
|---|
| 132 | #define BSD43
|
|---|
| 133 | #endif
|
|---|
| 134 | /*--------------------------------------------------------------------------*/
|
|---|
| 135 |
|
|---|
| 136 | #if !defined(UNDER_CE)
|
|---|
| 137 | #include <signal.h>
|
|---|
| 138 | #include <ctype.h>
|
|---|
| 139 | #include <errno.h>
|
|---|
| 140 | #include <sys/types.h>
|
|---|
| 141 | #endif
|
|---|
| 142 |
|
|---|
| 143 | #if defined(SYSV)
|
|---|
| 144 |
|
|---|
| 145 | #if defined(__osf__)
|
|---|
| 146 | #include <sys/socket.h>
|
|---|
| 147 | #include <netinet/in.h>
|
|---|
| 148 | #include <netinet/tcp.h>
|
|---|
| 149 | #include <arpa/inet.h>
|
|---|
| 150 | #include <netdb.h>
|
|---|
| 151 | #include <sys/time.h> /* struct timeval */
|
|---|
| 152 | #include <sys/resource.h> /* definition of struct rusage */
|
|---|
| 153 |
|
|---|
| 154 | #else /* else of __osf__ */
|
|---|
| 155 | #if defined(__NTVIS__)
|
|---|
| 156 | #include <winsock2.h>
|
|---|
| 157 | #include <windows.h> /* required for all Windows applications */
|
|---|
| 158 | #include <ws2tcpip.h>
|
|---|
| 159 | #include <memory.h>
|
|---|
| 160 | #include <time.h>
|
|---|
| 161 | #if !defined(UNDER_CE)
|
|---|
| 162 | #include <sys\timeb.h>
|
|---|
| 163 | #include <fcntl.h>
|
|---|
| 164 | #endif
|
|---|
| 165 | #include <stdlib.h>
|
|---|
| 166 | #include <io.h>
|
|---|
| 167 | struct rusage { struct timeval ru_utime, ru_stime; };
|
|---|
| 168 | #define RUSAGE_SELF 0
|
|---|
| 169 | #else /* else of __NTVIS__ */
|
|---|
| 170 | #if defined(__lynx__)
|
|---|
| 171 | #include <socket.h> /* located in /usr/include/..... */
|
|---|
| 172 | #include <netinet/in.h>
|
|---|
| 173 | #include <netinet/tcp.h>
|
|---|
| 174 | #include <arpa/inet.h>
|
|---|
| 175 | #include <netdb.h>
|
|---|
| 176 | #include <time.h>
|
|---|
| 177 | #include <resource.h> /* definition of struct rusage */
|
|---|
| 178 | #include <sys/times.h>
|
|---|
| 179 | #define RUSAGE_SELF 0
|
|---|
| 180 | #include <conf.h> /* definition of TICKSPERSEC (HZ) */
|
|---|
| 181 | #include <sys/param.h>
|
|---|
| 182 |
|
|---|
| 183 | #else /* else of __Lynx__ */
|
|---|
| 184 | #if defined(__svr4__)
|
|---|
| 185 | #include <sys/socket.h>
|
|---|
| 186 | #include <sys/uio.h>
|
|---|
| 187 | #include <netinet/in.h>
|
|---|
| 188 | #include <netinet/tcp.h>
|
|---|
| 189 | #include <arpa/inet.h>
|
|---|
| 190 | #include <netdb.h>
|
|---|
| 191 | #include <sys/time.h> /* struct timeval */
|
|---|
| 192 | #include <sys/resource.h> /* definition of struct rusage */
|
|---|
| 193 | #include <sys/times.h>
|
|---|
| 194 | #define RUSAGE_SELF 0
|
|---|
| 195 | #include <sys/param.h>
|
|---|
| 196 |
|
|---|
| 197 | #else /* else of __svr4__ all SYSV cases except those mentionned before */
|
|---|
| 198 | #include <sys/socket.h>
|
|---|
| 199 | #include <netinet/in.h>
|
|---|
| 200 | #include <netinet/tcp.h>
|
|---|
| 201 | #include <arpa/inet.h>
|
|---|
| 202 | #include <netdb.h>
|
|---|
| 203 | #include <sys/time.h> /* struct timeval */
|
|---|
| 204 | #include <sys/resource.h> /* definition of struct rusage */
|
|---|
| 205 | #include <sys/times.h>
|
|---|
| 206 | #define RUSAGE_SELF 0
|
|---|
| 207 | #include <sys/param.h>
|
|---|
| 208 |
|
|---|
| 209 | #endif /* __svr4__ */
|
|---|
| 210 | #endif /* __lynx__ */
|
|---|
| 211 | #endif /* __NTVIS__ */
|
|---|
| 212 | #endif /* __osf__ */
|
|---|
| 213 |
|
|---|
| 214 | #else /* else of SYSV it is a BSD OS */
|
|---|
| 215 | #include <stdlib.h>
|
|---|
| 216 | #include <string.h>
|
|---|
| 217 | #include <sys/socket.h>
|
|---|
| 218 | #include <netinet/in.h>
|
|---|
| 219 | #include <netinet/tcp.h>
|
|---|
| 220 | #include <arpa/inet.h>
|
|---|
| 221 | #include <netdb.h>
|
|---|
| 222 | #if defined(__linux__)
|
|---|
| 223 | #include <time.h> /* struct timeval */
|
|---|
| 224 | #else
|
|---|
| 225 | #include <sys/time.h> /* struct timeval */
|
|---|
| 226 | #endif
|
|---|
| 227 | #include <sys/resource.h> /* definition of struct rusage */
|
|---|
| 228 | #include <unistd.h> /* for usleep() - henry */
|
|---|
| 229 | #define SOCKET_ERROR -1
|
|---|
| 230 |
|
|---|
| 231 | #endif /* SYSV */
|
|---|
| 232 |
|
|---|
| 233 | #if defined(__NTVIS__)
|
|---|
| 234 |
|
|---|
| 235 | #if defined(_DEBUG) /* usual debug symbol for VC++ */
|
|---|
| 236 | #define DEBUG 1
|
|---|
| 237 | #endif
|
|---|
| 238 |
|
|---|
| 239 | void usleep(unsigned int microseconds);
|
|---|
| 240 |
|
|---|
| 241 | #define bcopy(a,b,n) memcpy((b), (a), (n))
|
|---|
| 242 | #define bzero(a,n) memset((a), 0, (n))
|
|---|
| 243 |
|
|---|
| 244 | #ifndef _GETOPT_
|
|---|
| 245 | #define _GETOPT_
|
|---|
| 246 | int getopt(int argc, char **argv, char *optstring);
|
|---|
| 247 |
|
|---|
| 248 | extern char *optarg; // returned arg to go with this option
|
|---|
| 249 | extern int optind; // index to next argv element to process
|
|---|
| 250 | extern int opterr; // should error messages be printed?
|
|---|
| 251 | extern int optopt; //
|
|---|
| 252 |
|
|---|
| 253 | #define BADCH ('?')
|
|---|
| 254 | #endif // _GETOPT
|
|---|
| 255 |
|
|---|
| 256 | /* get option letter from argument vector */
|
|---|
| 257 | int
|
|---|
| 258 | opterr = 1, // should error messages be printed?
|
|---|
| 259 | optind = 1, // index into parent argv vector
|
|---|
| 260 | optopt; // character checked for validity
|
|---|
| 261 | char *optarg; // argument associated with option
|
|---|
| 262 |
|
|---|
| 263 | #define EMSG ""
|
|---|
| 264 | char *progname; // may also be defined elsewhere
|
|---|
| 265 | #endif /*__NTVIS__*/
|
|---|
| 266 |
|
|---|
| 267 | /* sockaddr_in == file server address structure
|
|---|
| 268 | *
|
|---|
| 269 | * Socket address, internet style. declared in : /netinet/in.h
|
|---|
| 270 | * struct sockaddr_in {short sin_family;
|
|---|
| 271 | * u_short sin_port;
|
|---|
| 272 | * struct in_addr sin_addr;
|
|---|
| 273 | * char sin_zero[8];
|
|---|
| 274 | * };
|
|---|
| 275 | *
|
|---|
| 276 | * Structure used by kernel to store most addresses. declared in ./sys/socket.h
|
|---|
| 277 | * struct sockaddr{u_short sa_family; address family
|
|---|
| 278 | * char sa_data[14]; up to 14 bytes of direct address
|
|---|
| 279 | * };
|
|---|
| 280 | * PS : sin stand for "socket internet number"
|
|---|
| 281 | */
|
|---|
| 282 |
|
|---|
| 283 | #ifndef __NTVIS__
|
|---|
| 284 | #define FAR
|
|---|
| 285 | #endif
|
|---|
| 286 |
|
|---|
| 287 | #if defined(__CONST_SOCKADDR_ARG)
|
|---|
| 288 | #define SOCKADDR_CAST (__CONST_SOCKADDR_ARG)
|
|---|
| 289 | #elif defined(__lynx__) || defined(__sun__) || defined(_AIX) || defined(__FreeBSD__) || defined(__NTVIS__)
|
|---|
| 290 | #define SOCKADDR_CAST (struct sockaddr FAR *)
|
|---|
| 291 | #else
|
|---|
| 292 | #define SOCKADDR_CAST
|
|---|
| 293 | #endif
|
|---|
| 294 |
|
|---|
| 295 | #if defined(__sun__)
|
|---|
| 296 | struct sockaddr_in sockaddr; /* done in ./X11/Xdmcp.h */
|
|---|
| 297 | #endif
|
|---|
| 298 |
|
|---|
| 299 | struct sockaddr_in sinme; /* is the socket struct. in the local host */
|
|---|
| 300 | struct sockaddr_in sinhim; /* is the socket struc. in the remote host */
|
|---|
| 301 |
|
|---|
| 302 | #if defined(__lynx__) || defined(__svr4__) || defined(_AIX)
|
|---|
| 303 | struct sockaddr frominet;
|
|---|
| 304 | #else
|
|---|
| 305 | struct sockaddr_in frominet;
|
|---|
| 306 | #endif /* __lynx__ */
|
|---|
| 307 |
|
|---|
| 308 | int domain, fromlen;
|
|---|
| 309 |
|
|---|
| 310 | #if !defined(__NTVIS__)
|
|---|
| 311 | #define SOCKET int
|
|---|
| 312 | #endif /* __NTVIS__ */
|
|---|
| 313 | SOCKET fd; /* fd of network socket */
|
|---|
| 314 |
|
|---|
| 315 | #if !defined(__lynx__)
|
|---|
| 316 | extern int errno;
|
|---|
| 317 | #endif
|
|---|
| 318 |
|
|---|
| 319 | #include <stdio.h>
|
|---|
| 320 |
|
|---|
| 321 | FILE *fplog = NULL; /* file pointer for the log file */
|
|---|
| 322 | char logfile[100]; /* file name for the log */
|
|---|
| 323 | static char logfile_head[] ="ttcp_log"; /* header name for the log */
|
|---|
| 324 | int buflen = 8 * 1024; /* length of buffer */
|
|---|
| 325 | char *buf; /* ptr to dynamic buffer */
|
|---|
| 326 | int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */
|
|---|
| 327 |
|
|---|
| 328 | #define START_PKT_LEN 4
|
|---|
| 329 | #define START_PATTERN_LEN 4
|
|---|
| 330 | #define END_PKT_LEN 8
|
|---|
| 331 | #define END_PATTERN_LEN 4
|
|---|
| 332 | #define MIN_UDP_LEN 5
|
|---|
| 333 |
|
|---|
| 334 | char start_pattern[START_PATTERN_LEN] = {1, 2, 3, 4};
|
|---|
| 335 | char end_pattern[END_PATTERN_LEN] = {2, 2, 2, 2};
|
|---|
| 336 |
|
|---|
| 337 | int bufoffset = 0; /* align buffer to this */
|
|---|
| 338 | int bufalign = 16*1024; /* modulo this */
|
|---|
| 339 |
|
|---|
| 340 | int udp = 0; /* 0 = tcp, !0 = udp */
|
|---|
| 341 | int options = 0; /* socket options */
|
|---|
| 342 | int one = 1; /* for 4.3 BSD style setsockopt() */
|
|---|
| 343 | short port = 5010; /* TCP port number */
|
|---|
| 344 | char *host; /* ptr to name of host */
|
|---|
| 345 | int rndm = 0; /* 0="normal", !0=random data */
|
|---|
| 346 | int trans; /* 0=receive, !0=transmit mode */
|
|---|
| 347 | int timeout; /* read timeout in millisec */
|
|---|
| 348 | int debug = 0; /* 0=No-Debug, 1=Debug-Set-On */
|
|---|
| 349 | int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */
|
|---|
| 350 | int verbose = 0; /* 0=print basic info, 1=print cpu rate,
|
|---|
| 351 | * proc resource usage. */
|
|---|
| 352 | int nodelay = 0; /* set TCP_NODELAY socket option */
|
|---|
| 353 | int pri = 0; /* link layer priority */
|
|---|
| 354 | int b_flag = 0; /* use mread() */
|
|---|
| 355 | int log_cnt = 0; /* append result to a log */
|
|---|
| 356 | int sockbufsize = 0; /* socket buffer size to use */
|
|---|
| 357 | char fmt = 'A'; /* output format:
|
|---|
| 358 | * b = bits, B = bytes,
|
|---|
| 359 | * k = kilobits, K = kilobytes,
|
|---|
| 360 | * m = megabits, M = megabytes,
|
|---|
| 361 | * g = gigabits, G = gigabytes,
|
|---|
| 362 | * A = automatic Xbytes (default) */
|
|---|
| 363 | int touchdata = 0; /* access data after reading */
|
|---|
| 364 | int seq_info = 0; /* report out of order seq nums */
|
|---|
| 365 |
|
|---|
| 366 | int hash = 0; /* print hash marks for each buffer */
|
|---|
| 367 | int udpsleep = 0; /* sleep in between udp buffers */
|
|---|
| 368 | int burstn = 1; /* number of buffers per burst */
|
|---|
| 369 | int bufmin = -1; /* minimum buffer size to use when
|
|---|
| 370 | sending random-size buffers */
|
|---|
| 371 | unsigned int seed = 1; /* seed for random number generator
|
|---|
| 372 | used for random buffer lengths */
|
|---|
| 373 | int no_start = 0; /* skip the start frames for UDP */
|
|---|
| 374 | int no_data = 0; /* skip all data frames for UDP */
|
|---|
| 375 | int no_end = 0; /* skip the end frames for UDP */
|
|---|
| 376 |
|
|---|
| 377 | double nbytes; /* bytes on net */
|
|---|
| 378 | unsigned long numCalls; /* # of I/O system calls */
|
|---|
| 379 |
|
|---|
| 380 | struct hostent *addr;
|
|---|
| 381 | extern int optind;
|
|---|
| 382 | extern char *optarg;
|
|---|
| 383 |
|
|---|
| 384 | #if defined(UNDER_CE)
|
|---|
| 385 | static int errno;
|
|---|
| 386 | static char *weekday[] ={"Sun", "Mon","Tues", "Wed", "Thurs", "Fri", "Sat"};
|
|---|
| 387 | static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "July", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
|---|
| 388 | #define perror printf
|
|---|
| 389 | #endif
|
|---|
| 390 |
|
|---|
| 391 | /*--------------------------------------------------------------------------*/
|
|---|
| 392 | static struct timeval time0; /* Time at which timing started */
|
|---|
| 393 | static struct timeval time1;
|
|---|
| 394 | static struct rusage ru0; /* Resource utilization at the start */
|
|---|
| 395 | static struct rusage ru1;
|
|---|
| 396 | static struct tm *tms; /* system time structure */
|
|---|
| 397 |
|
|---|
| 398 |
|
|---|
| 399 | /*-----------Prototype functions definitions -------------------------------*/
|
|---|
| 400 | /*--------------------------------------------------------------------------*/
|
|---|
| 401 |
|
|---|
| 402 | /* ANSI input/output functions (stdio.h) */
|
|---|
| 403 |
|
|---|
| 404 | #if defined(__lynx__)
|
|---|
| 405 | int getopt(int, char**, char*);
|
|---|
| 406 | int gettimeofday(struct timeval *tp, struct timezone *tzp);
|
|---|
| 407 |
|
|---|
| 408 | #else
|
|---|
| 409 | #if defined(__svr4__)
|
|---|
| 410 |
|
|---|
| 411 | #else
|
|---|
| 412 | #if defined(_AIX)
|
|---|
| 413 |
|
|---|
| 414 | #else
|
|---|
| 415 | #if defined(__hpux__)
|
|---|
| 416 | #else
|
|---|
| 417 | #if defined(__NTVIS__)
|
|---|
| 418 | #else
|
|---|
| 419 | #if defined(BSD42) || defined(BSD43)
|
|---|
| 420 | #else
|
|---|
| 421 |
|
|---|
| 422 | int printf( char*, ...);
|
|---|
| 423 | int fprintf(FILE*,char*, ...);
|
|---|
| 424 | void perror(char*);
|
|---|
| 425 | int getopt(int, char**, char*);
|
|---|
| 426 | int gettimeofday(struct timeval *tp, struct timezone *tzp);
|
|---|
| 427 | #endif /* BSD42 || BSD43 */
|
|---|
| 428 | #endif /* __NTVIS__ */
|
|---|
| 429 | #endif /* __hpux__ */
|
|---|
| 430 | #endif /* _AIX */
|
|---|
| 431 | #endif /* __svr4__ */
|
|---|
| 432 | #endif /* __lynx__ */
|
|---|
| 433 |
|
|---|
| 434 | int main(int argc, char* argv[]);
|
|---|
| 435 | #if ( (!(defined(BSD42))) && (!(defined(BSD43))) && (!(defined(__NTVIS__))) )
|
|---|
| 436 | int read(int, char*, int);
|
|---|
| 437 | int write(int, char*, int);
|
|---|
| 438 | int close(int);
|
|---|
| 439 | #endif /* !(BSD42) && !(BSD43) */
|
|---|
| 440 | int fclose(FILE *stream);
|
|---|
| 441 |
|
|---|
| 442 | #if !defined(BSD43) && !defined(__NTVIS__)
|
|---|
| 443 | void bzero(char*,int);
|
|---|
| 444 | void bcopy(char*, char*, int);
|
|---|
| 445 | char strncpy(char *s1,char *s2,size_t n);
|
|---|
| 446 | int atoi(char*);
|
|---|
| 447 | int malloc(int);
|
|---|
| 448 | #endif
|
|---|
| 449 |
|
|---|
| 450 |
|
|---|
| 451 | /* ANSI socket functions prototype /sys/socket.h */
|
|---|
| 452 | #if defined(__lynx__)
|
|---|
| 453 | int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
|
|---|
| 454 |
|
|---|
| 455 | #else
|
|---|
| 456 | #if defined(__svr4__) && !defined(sparc)
|
|---|
| 457 |
|
|---|
| 458 | /* informations in : /usr/include/sys/socket.h */
|
|---|
| 459 | int socket(int, int, int);
|
|---|
| 460 | int connect(int, struct sockaddr *, int);
|
|---|
| 461 | int bind(int, struct sockaddr *, int);
|
|---|
| 462 | int listen(int, int);
|
|---|
| 463 | int accept(int, struct sockaddr *, int *);
|
|---|
| 464 | int sendto(int, const char *, int, int, const struct sockaddr *, int);
|
|---|
| 465 | int recvfrom(int, char *, int, int, struct sockaddr *, int *);
|
|---|
| 466 | int getpeername(int, struct sockaddr *, int *);
|
|---|
| 467 | int getsockopt(int, int, int, char *, int *);
|
|---|
| 468 | int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
|
|---|
| 469 |
|
|---|
| 470 | #else
|
|---|
| 471 | #if defined(_AIX)
|
|---|
| 472 | int select(unsigned long, void *, void *, void *, struct timeval *);
|
|---|
| 473 |
|
|---|
| 474 | #else
|
|---|
| 475 | #if defined(__hpux__)
|
|---|
| 476 | int getrusage(int who,struct rusage *rusage);
|
|---|
| 477 |
|
|---|
| 478 | #else
|
|---|
| 479 | #if defined(__NTVIS__)
|
|---|
| 480 |
|
|---|
| 481 | #else
|
|---|
| 482 | #if defined(BSD42) || defined(BSD43)
|
|---|
| 483 |
|
|---|
| 484 | #else
|
|---|
| 485 |
|
|---|
| 486 | int socket(int, int, int);
|
|---|
| 487 | int connect(int s,struct sockaddr_in *name, int namelen);
|
|---|
| 488 | int bind(int s,struct sockaddr *name,int namelen);
|
|---|
| 489 | int listen(int, int);
|
|---|
| 490 | int accept(int, struct sockaddr_in *, int *);
|
|---|
| 491 | int sendto(int, char *, int, int, struct sockaddr_in *, int);
|
|---|
| 492 | int recvfrom(int, char *, int, int, struct sockaddr_in *, int *);
|
|---|
| 493 | int getpeername(int, struct sockaddr *, int *);
|
|---|
| 494 | int setsockopt(int, int, int, char *, int);
|
|---|
| 495 |
|
|---|
| 496 | int getsockopt(int, int, int, char*, int*);
|
|---|
| 497 | int select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
|
|---|
| 498 |
|
|---|
| 499 | #endif /* BSD42 || BSD43 */
|
|---|
| 500 | #endif /* __hpux__ */
|
|---|
| 501 | #endif /* _AIX */
|
|---|
| 502 | #endif /* __svr4__ */
|
|---|
| 503 | #endif /* __lynx__ */
|
|---|
| 504 | #endif /* __NTVIS__ */
|
|---|
| 505 |
|
|---|
| 506 | /* ttcp prototype functions */
|
|---|
| 507 | void udp_rcv_test(void);
|
|---|
| 508 | double calc_cpu_time(struct rusage *r0, struct rusage *r1);
|
|---|
| 509 | double calc_real_time(struct timeval *t0, struct timeval *t1);
|
|---|
| 510 | int getrusage(int who,struct rusage *rusage);
|
|---|
| 511 | void sockets_err(char*);
|
|---|
| 512 | void err(char *);
|
|---|
| 513 | void mes(char *);
|
|---|
| 514 | void pattern(char *, int);
|
|---|
| 515 | int Nread(SOCKET, void *, int);
|
|---|
| 516 | int Nwrite(int, void *, int);
|
|---|
| 517 | void delay(int);
|
|---|
| 518 | int mread(int, char *,unsigned);
|
|---|
| 519 | char *outfmt(char format, double b);
|
|---|
| 520 | void prep_timer(void);
|
|---|
| 521 | void read_timer(void);
|
|---|
| 522 | void result_summary(void);
|
|---|
| 523 | void prusage(struct rusage*, struct rusage*,
|
|---|
| 524 | struct timeval*, struct timeval*);
|
|---|
| 525 | void tvadd(struct timeval *tsum, struct timeval *t0,struct timeval *t1);
|
|---|
| 526 | void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0);
|
|---|
| 527 | void psecs(int);
|
|---|
| 528 | void open_log(void);
|
|---|
| 529 | void close_log(void);
|
|---|
| 530 | void do_Usage(void);
|
|---|
| 531 | void do_help(void);
|
|---|
| 532 |
|
|---|
| 533 | /*--------------------------------------------------------------------------*/
|
|---|
| 534 | #if !defined(__NTVIS__)
|
|---|
| 535 | void
|
|---|
| 536 | sigpipe()
|
|---|
| 537 | {;
|
|---|
| 538 | }
|
|---|
| 539 | #endif
|
|---|
| 540 | /*--------------------------------------------------------------------------*/
|
|---|
| 541 | /*--------------------------------------------------------------------------*/
|
|---|
| 542 | int
|
|---|
| 543 | main(int argc, char **argv)
|
|---|
| 544 | {
|
|---|
| 545 | unsigned long addr_tmp;
|
|---|
| 546 | int c,k;
|
|---|
| 547 | int sockbufsndsize,sockbufrcvsize;
|
|---|
| 548 | int sockbuflen;
|
|---|
| 549 | struct sockaddr_in peer;
|
|---|
| 550 | int peerlen = sizeof(peer);
|
|---|
| 551 |
|
|---|
| 552 | #if defined(__NTVIS__)
|
|---|
| 553 | extern char *optarg;
|
|---|
| 554 | WSADATA WSAData;
|
|---|
| 555 | WSAStartup(MAKEWORD(1,1), &WSAData);
|
|---|
| 556 | #endif /* __NTVIS__ */
|
|---|
| 557 |
|
|---|
| 558 | if (argc < 2) { do_Usage(); exit(1); }
|
|---|
| 559 |
|
|---|
| 560 | while (1) {
|
|---|
| 561 | while ((c=getopt(argc, argv, "hidrstuvxHVBDTLb:f:l:n:p:A:O:S:N:P:R:I:w:")) != -1) {
|
|---|
| 562 | switch (c) {
|
|---|
| 563 | case 'w':
|
|---|
| 564 | timeout = atoi(optarg);
|
|---|
| 565 | break;
|
|---|
| 566 | case 'I':
|
|---|
| 567 | seed = atoi(optarg);
|
|---|
| 568 | break;
|
|---|
| 569 | case 'N':
|
|---|
| 570 | burstn = atoi(optarg);
|
|---|
| 571 | break;
|
|---|
| 572 | case 'P':
|
|---|
| 573 | #if defined(__linux__)
|
|---|
| 574 | pri = atoi(optarg);
|
|---|
| 575 | break;
|
|---|
| 576 | #else
|
|---|
| 577 | fprintf(stderr, "ttcp: -P option not supported on this OS\n");
|
|---|
| 578 | exit(1);
|
|---|
| 579 | #endif
|
|---|
| 580 | case 'R':
|
|---|
| 581 | bufmin = atoi(optarg);
|
|---|
| 582 | break;
|
|---|
| 583 | case 'S':
|
|---|
| 584 | udpsleep = atoi(optarg);
|
|---|
| 585 | if (udpsleep < 0) udpsleep = 0;
|
|---|
| 586 | /* convert msec arg to usec for usleep, minimum 10ms */
|
|---|
| 587 | udpsleep = udpsleep * 1000;
|
|---|
| 588 | break;
|
|---|
| 589 | case 'H':
|
|---|
| 590 | hash = 1;
|
|---|
| 591 | break;
|
|---|
| 592 | case 'V':
|
|---|
| 593 | fprintf(stdout,"%s %s\n" , RCSid , VersDate );
|
|---|
| 594 | exit(0);
|
|---|
| 595 | case 'B':
|
|---|
| 596 | b_flag = 1;
|
|---|
| 597 | break;
|
|---|
| 598 | case 'L':
|
|---|
| 599 | log_cnt = 1;
|
|---|
| 600 | break;
|
|---|
| 601 | case 'h':
|
|---|
| 602 | do_help();
|
|---|
| 603 | exit(1);
|
|---|
| 604 | break;
|
|---|
| 605 | case 't':
|
|---|
| 606 | trans = 1;
|
|---|
| 607 | break;
|
|---|
| 608 | case 'r':
|
|---|
| 609 | trans = 0;
|
|---|
| 610 | break;
|
|---|
| 611 | case 'x':
|
|---|
| 612 | rndm = 1;
|
|---|
| 613 | break;
|
|---|
| 614 | case 'd':
|
|---|
| 615 | options |= SO_DEBUG;
|
|---|
| 616 | break;
|
|---|
| 617 | case 'D':
|
|---|
| 618 | #ifdef TCP_NODELAY
|
|---|
| 619 | nodelay = 1;
|
|---|
| 620 | #else
|
|---|
| 621 | fprintf(stderr,
|
|---|
| 622 | "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n");
|
|---|
| 623 | #endif
|
|---|
| 624 | break;
|
|---|
| 625 | case 'n':
|
|---|
| 626 | nbuf = atoi(optarg);
|
|---|
| 627 | break;
|
|---|
| 628 | case 'l':
|
|---|
| 629 | buflen = atoi(optarg);
|
|---|
| 630 | break;
|
|---|
| 631 | case 's':
|
|---|
| 632 | sinkmode = !sinkmode;
|
|---|
| 633 | break;
|
|---|
| 634 | case 'p':
|
|---|
| 635 | port = atoi(optarg);
|
|---|
| 636 | break;
|
|---|
| 637 | case 'u':
|
|---|
| 638 | udp = 1;
|
|---|
| 639 | break;
|
|---|
| 640 | case 'v':
|
|---|
| 641 | verbose = 1;
|
|---|
| 642 | break;
|
|---|
| 643 | case 'A':
|
|---|
| 644 | bufalign = atoi(optarg);
|
|---|
| 645 | break;
|
|---|
| 646 | case 'O':
|
|---|
| 647 | bufoffset = atoi(optarg);
|
|---|
| 648 | break;
|
|---|
| 649 | case 'b':
|
|---|
| 650 | #if defined(SO_SNDBUF) || defined(SO_RCVBUF)
|
|---|
| 651 | sockbufsize = atoi(optarg);
|
|---|
| 652 | #else
|
|---|
| 653 | fprintf(stderr,
|
|---|
| 654 | "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n");
|
|---|
| 655 | #endif
|
|---|
| 656 | break;
|
|---|
| 657 | case 'f':
|
|---|
| 658 | fmt = *optarg;
|
|---|
| 659 | break;
|
|---|
| 660 | case 'T':
|
|---|
| 661 | touchdata = 1;
|
|---|
| 662 | break;
|
|---|
| 663 | case 'i':
|
|---|
| 664 | seq_info = 1;
|
|---|
| 665 | break;
|
|---|
| 666 |
|
|---|
| 667 | default:
|
|---|
| 668 | {do_Usage(); exit(1);}
|
|---|
| 669 | }/*switch */
|
|---|
| 670 | }/* while getopt() */
|
|---|
| 671 |
|
|---|
| 672 | argc -= optind;
|
|---|
| 673 | argv += optind;
|
|---|
| 674 | optind = 0;
|
|---|
| 675 |
|
|---|
| 676 | /* check for '--' args */
|
|---|
| 677 | if (argc == 0) {
|
|---|
| 678 | /* no more args */
|
|---|
| 679 | break; /* while (1) */
|
|---|
| 680 | #if defined(DEBUG)
|
|---|
| 681 | } else if (!strcmp(argv[0], "--nostart")) {
|
|---|
| 682 | no_start = 1;
|
|---|
| 683 | argc--; argv++;
|
|---|
| 684 | } else if (!strcmp(argv[0], "--nodata")) {
|
|---|
| 685 | no_data = 1;
|
|---|
| 686 | argc--; argv++;
|
|---|
| 687 | } else if (!strcmp(argv[0], "--noend")) {
|
|---|
| 688 | no_end = 1;
|
|---|
| 689 | argc--; argv++;
|
|---|
| 690 | } else if (!strcmp(argv[0], "--debug")) {
|
|---|
| 691 | debug = 1;
|
|---|
| 692 | argc--; argv++;
|
|---|
| 693 | #endif /* DEBUG */
|
|---|
| 694 | } else if (!strncmp(argv[0], "--", 2)) {
|
|---|
| 695 | fprintf(stderr, "ttcp: illegal option: %s\n", argv[0]);
|
|---|
| 696 | do_Usage(); exit(1);
|
|---|
| 697 | } else {
|
|---|
| 698 | /* the arg was not a '--' arg */
|
|---|
| 699 | break; /* while (1) */
|
|---|
| 700 | }
|
|---|
| 701 | } /* while (1) */
|
|---|
| 702 |
|
|---|
| 703 |
|
|---|
| 704 | /* ----------------------- main part ----------------------- */
|
|---|
| 705 |
|
|---|
| 706 | #if defined(__NTVIS__) && !defined(UNDER_CE)
|
|---|
| 707 | /* Set "stdin" to have binary mode: */
|
|---|
| 708 | if (_setmode(_fileno(stdin), _O_BINARY) == -1)
|
|---|
| 709 | perror("%s: Error setting stdin to binary mode");
|
|---|
| 710 | /* Set "stdout" to have binary mode: */
|
|---|
| 711 | if (_setmode(_fileno(stdout), _O_BINARY) == -1)
|
|---|
| 712 | perror("%s: Error setting stdout to binary mode");
|
|---|
| 713 | #endif /* __NTVIS__ */
|
|---|
| 714 |
|
|---|
| 715 | if (log_cnt) open_log();
|
|---|
| 716 |
|
|---|
| 717 | /* input error checking */
|
|---|
| 718 | if (burstn > nbuf) {
|
|---|
| 719 | fprintf(stderr, "ttcp: buffers per burst must be less than or equal to "
|
|---|
| 720 | "total number of buffers\n");
|
|---|
| 721 | exit(1);
|
|---|
| 722 | }
|
|---|
| 723 | if (bufmin < -1) {
|
|---|
| 724 | fprintf(stderr, "ttcp: minimum buffer size specified with -R option must "
|
|---|
| 725 | "be non-negative\n");
|
|---|
| 726 | exit(1);
|
|---|
| 727 | }
|
|---|
| 728 | if (buflen > 65535) {
|
|---|
| 729 | fprintf(stderr, "ttcp: maximum buffer size specified with -l option must "
|
|---|
| 730 | "be <= 65536\n");
|
|---|
| 731 | exit(1);
|
|---|
| 732 | }
|
|---|
| 733 | if (bufmin > buflen) {
|
|---|
| 734 | fprintf(stderr, "ttcp: minimum buffer size specified with -R option must "
|
|---|
| 735 | "be less than or equal to (maximum) buffer size specified with -l\n");
|
|---|
| 736 | exit(1);
|
|---|
| 737 | }
|
|---|
| 738 |
|
|---|
| 739 | /* buffer allocation */
|
|---|
| 740 |
|
|---|
| 741 | if (udp && buflen < MIN_UDP_LEN)
|
|---|
| 742 | buflen = MIN_UDP_LEN; /* send more than the sentinel size */
|
|---|
| 743 |
|
|---|
| 744 | if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL)
|
|---|
| 745 | err("malloc");
|
|---|
| 746 | if (bufalign != 0)
|
|---|
| 747 | buf +=(bufalign - ((int)buf % bufalign) + bufoffset) % bufalign;
|
|---|
| 748 |
|
|---|
| 749 | fprintf(stderr,"ttcp%s: buflen=%d, nbuf=%d, align=%d/%d, port=%d\n",
|
|---|
| 750 | trans?"-t":"-r",buflen, nbuf, bufalign, bufoffset, port);
|
|---|
| 751 | if (log_cnt)fprintf(fplog," %6d %6d %6d %6d %4d",
|
|---|
| 752 | buflen, nbuf, bufalign, bufoffset, port);
|
|---|
| 753 |
|
|---|
| 754 | /* preload the buffer for the transmit condition */
|
|---|
| 755 | pattern( buf, buflen );
|
|---|
| 756 |
|
|---|
| 757 | /* seed the random number generator */
|
|---|
| 758 | if ((bufmin != -1) || (rndm != 0)) {
|
|---|
| 759 | #if defined(__NTVIS__)
|
|---|
| 760 | srand(seed);
|
|---|
| 761 | #else /* ! __NTVIS__ */
|
|---|
| 762 | srandom(seed);
|
|---|
| 763 | #endif /* __NTVIS__ */
|
|---|
| 764 | }
|
|---|
| 765 |
|
|---|
| 766 | if(trans)
|
|---|
| 767 | {/* xmitr */
|
|---|
| 768 | if (argc == 0) {
|
|---|
| 769 | fprintf(stderr, "ttcp: missing destination host arg\n");
|
|---|
| 770 | do_Usage(); exit(1);
|
|---|
| 771 | }
|
|---|
| 772 |
|
|---|
| 773 | bzero((char *)&sinhim, sizeof(sinhim));
|
|---|
| 774 | host = argv[0];
|
|---|
| 775 | if (atoi(host) > 0 )
|
|---|
| 776 | {/* Numeric */
|
|---|
| 777 | sinhim.sin_family = AF_INET;
|
|---|
| 778 | sinhim.sin_addr.s_addr = inet_addr(host);
|
|---|
| 779 | }
|
|---|
| 780 | else
|
|---|
| 781 | {if ((addr=gethostbyname(host)) == NULL) sockets_err("bad hostname");
|
|---|
| 782 | sinhim.sin_family = addr->h_addrtype;
|
|---|
| 783 | bcopy(addr->h_addr,(char*)&addr_tmp, addr->h_length);
|
|---|
| 784 | sinhim.sin_addr.s_addr = addr_tmp;
|
|---|
| 785 | }
|
|---|
| 786 | sinhim.sin_port = htons(port);
|
|---|
| 787 | sinme.sin_port = 0; /* free choice */
|
|---|
| 788 | }
|
|---|
| 789 | else
|
|---|
| 790 | {/* rcvr */
|
|---|
| 791 | sinme.sin_port = htons(port);
|
|---|
| 792 | }
|
|---|
| 793 | #if defined(__NTVIS__)
|
|---|
| 794 | sinme.sin_family = AF_INET;
|
|---|
| 795 | #endif
|
|---|
| 796 |
|
|---|
| 797 | fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0);
|
|---|
| 798 |
|
|---|
| 799 | #if defined(__NTVIS__)
|
|---|
| 800 | if (fd == INVALID_SOCKET) sockets_err("socket");
|
|---|
| 801 | #else
|
|---|
| 802 | if (fd < 0) sockets_err("socket");
|
|---|
| 803 | #endif
|
|---|
| 804 |
|
|---|
| 805 | if (verbose) {
|
|---|
| 806 | char *label = trans?"ttcp-t":"ttcp-r";
|
|---|
| 807 | #if defined(UNDER_CE)
|
|---|
| 808 | SYSTEMTIME SystemTime;
|
|---|
| 809 | char time_str[30];
|
|---|
| 810 |
|
|---|
| 811 | GetLocalTime(&SystemTime);
|
|---|
| 812 | sprintf(time_str, "%s %s %d %02d:%02d:%02d %d\n", weekday[SystemTime.wDayOfWeek], month[SystemTime.wMonth - 1],
|
|---|
| 813 | SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wYear);
|
|---|
| 814 | #else
|
|---|
| 815 | time_t now;
|
|---|
| 816 | char *time_str;
|
|---|
| 817 |
|
|---|
| 818 | time(&now);
|
|---|
| 819 | time_str = ctime(&now);
|
|---|
| 820 | #endif
|
|---|
| 821 | fprintf(stdout,"%s: start time %s", label, time_str);
|
|---|
| 822 | fprintf(stdout,"%s: File-Descriptor 0x%x Opened\n", label, fd );
|
|---|
| 823 | }
|
|---|
| 824 |
|
|---|
| 825 | #if defined(__NTVIS__)
|
|---|
| 826 | if (bind(fd, (struct sockaddr FAR *)&sinme, sizeof(sinme)) == SOCKET_ERROR)
|
|---|
| 827 | sockets_err("bind");
|
|---|
| 828 | #else
|
|---|
| 829 | if (bind(fd, SOCKADDR_CAST &sinme, sizeof(sinme)) < 0)
|
|---|
| 830 | sockets_err("bind");
|
|---|
| 831 | #endif /* __NTVIS__ */
|
|---|
| 832 |
|
|---|
| 833 |
|
|---|
| 834 | #if defined(SO_SNDBUF) || defined(SO_RCVBUF)
|
|---|
| 835 | if (sockbufsize)
|
|---|
| 836 | {
|
|---|
| 837 | #if defined(__lynx__) || defined(__sun__) || defined(__NTVIS__)
|
|---|
| 838 | if (trans)
|
|---|
| 839 | {if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize,
|
|---|
| 840 | sizeof sockbufsize) < 0)
|
|---|
| 841 | sockets_err("setsockopt: sndbuf");
|
|---|
| 842 | }
|
|---|
| 843 | else
|
|---|
| 844 | {if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize,
|
|---|
| 845 | sizeof sockbufsize) < 0)
|
|---|
| 846 | sockets_err("setsockopt: rcvbuf");
|
|---|
| 847 | }
|
|---|
| 848 |
|
|---|
| 849 | #else
|
|---|
| 850 | if (trans)
|
|---|
| 851 |
|
|---|
| 852 | {if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
|
|---|
| 853 | sizeof sockbufsize) < 0)
|
|---|
| 854 | sockets_err("setsockopt: sndbuf");
|
|---|
| 855 | }
|
|---|
| 856 | else
|
|---|
| 857 | {if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
|
|---|
| 858 | sizeof sockbufsize) < 0)
|
|---|
| 859 | sockets_err("setsockopt: rcvbuf");
|
|---|
| 860 | }
|
|---|
| 861 | #endif /* __lynx__ __sun__ __NTVIS__ */
|
|---|
| 862 | }
|
|---|
| 863 | else
|
|---|
| 864 | {/*
|
|---|
| 865 | ** Added by Daniel Davids to Know Socket-Buffer-Sizes
|
|---|
| 866 | */
|
|---|
| 867 | sockbuflen = sizeof sockbufsndsize;
|
|---|
| 868 | #if defined(__lynx__) || defined(__sun__) || defined(__NTVIS__)
|
|---|
| 869 | getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsndsize,
|
|---|
| 870 | &sockbuflen);
|
|---|
| 871 | sockbuflen = sizeof sockbufrcvsize;
|
|---|
| 872 | getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufrcvsize,
|
|---|
| 873 | &sockbuflen);
|
|---|
| 874 | #else
|
|---|
| 875 | getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sockbufsndsize, &sockbuflen);
|
|---|
| 876 | sockbuflen = sizeof sockbufrcvsize;
|
|---|
| 877 | getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sockbufrcvsize, &sockbuflen);
|
|---|
| 878 | #endif /* __lynx__ __sun__ __NTVIS__ */
|
|---|
| 879 | sockbufsize = ( sockbufsndsize + sockbufrcvsize ) / 2;
|
|---|
| 880 |
|
|---|
| 881 | if ( sockbufsndsize != sockbufrcvsize )
|
|---|
| 882 | {fprintf(stderr, "sockbufsndsize=%d, ", sockbufsndsize );
|
|---|
| 883 | fprintf(stderr, "sockbufrcvsize=%d, ", sockbufrcvsize );
|
|---|
| 884 | }
|
|---|
| 885 | }
|
|---|
| 886 | #endif /* defined(SO_SNDBUF) || defined(SO_RCVBUF) */
|
|---|
| 887 |
|
|---|
| 888 | if (sockbufsize) fprintf(stderr, "sockbufsize=%d, \n", sockbufsize);
|
|---|
| 889 |
|
|---|
| 890 | if (log_cnt)
|
|---|
| 891 | {if (sockbufsize)fprintf(fplog," %6d",sockbufsize);
|
|---|
| 892 | else fprintf(fplog," 0");
|
|---|
| 893 | }
|
|---|
| 894 |
|
|---|
| 895 | #if defined(__linux__)
|
|---|
| 896 | if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (char *)&pri, sizeof pri) < 0)
|
|---|
| 897 | sockets_err("setsockopt: priority");
|
|---|
| 898 | #endif
|
|---|
| 899 |
|
|---|
| 900 |
|
|---|
| 901 | if (trans) fprintf(stderr, "# %s sender -> %s #\n", udp?"udp":"tcp", host);
|
|---|
| 902 | else fprintf(stderr, "# %s receiver #\n", udp?"udp":"tcp");
|
|---|
| 903 |
|
|---|
| 904 | if (!udp)
|
|---|
| 905 | {
|
|---|
| 906 | #if !defined(__NTVIS__)
|
|---|
| 907 | signal(SIGPIPE, sigpipe);
|
|---|
| 908 | #endif /* !__NTVIS__ */
|
|---|
| 909 |
|
|---|
| 910 | if (trans)
|
|---|
| 911 | {/* We are the client if transmitting */
|
|---|
| 912 | if (options)
|
|---|
| 913 | {
|
|---|
| 914 | #if defined(BSD42)
|
|---|
| 915 | if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0)
|
|---|
| 916 | #else /* BSD43 */
|
|---|
| 917 | if( setsockopt(fd, SOL_SOCKET, options, (char *)&one, sizeof(one)) < 0)
|
|---|
| 918 | #endif /* BDS42 */
|
|---|
| 919 | sockets_err("setsockopt");
|
|---|
| 920 | }
|
|---|
| 921 | #ifdef TCP_NODELAY
|
|---|
| 922 | if (nodelay)
|
|---|
| 923 | {struct protoent *p;
|
|---|
| 924 | p = getprotobyname("tcp");
|
|---|
| 925 | #if defined(__lynx__) || defined(__sun__) || defined(__NTVIS__)
|
|---|
| 926 | if( p && setsockopt(fd, p->p_proto, TCP_NODELAY,
|
|---|
| 927 | (char *) &one, sizeof(one)) < 0)
|
|---|
| 928 | #else
|
|---|
| 929 | if( p && setsockopt(fd, p->p_proto, TCP_NODELAY,
|
|---|
| 930 | &one, sizeof(one)) < 0)
|
|---|
| 931 | #endif /* __lynx__ __sun__ __NTVIS__ */
|
|---|
| 932 | sockets_err("setsockopt: nodelay");
|
|---|
| 933 | }
|
|---|
| 934 | #endif /* TCP_NODELAY */
|
|---|
| 935 | if (connect(fd, SOCKADDR_CAST &sinhim, sizeof(sinhim) ) < 0)
|
|---|
| 936 | sockets_err("connect");
|
|---|
| 937 | }/* if (trans) */
|
|---|
| 938 | else
|
|---|
| 939 | {/* otherwise, we are the server and should listen for connections */
|
|---|
| 940 |
|
|---|
| 941 | errno = 0;
|
|---|
| 942 |
|
|---|
| 943 | #if defined(sgi) || ( defined(__osf__) && !defined(_CFE) )
|
|---|
| 944 | if( listen(fd,1) <0 )
|
|---|
| 945 | #else
|
|---|
| 946 | if( listen(fd,0) <0 ) /* allow a queue of 0 */
|
|---|
| 947 | #endif
|
|---|
| 948 | sockets_err("listen");
|
|---|
| 949 |
|
|---|
| 950 | if(options) {
|
|---|
| 951 | int err;
|
|---|
| 952 | #if defined(BSD42)
|
|---|
| 953 | err = setsockopt(fd, SOL_SOCKET, options, 0, 0);
|
|---|
| 954 | #elif defined(__lynx__) || defined(__sun__) || defined(__NTVIS__)
|
|---|
| 955 | err = setsockopt(fd, SOL_SOCKET, options, (char *) &one, sizeof(one));
|
|---|
| 956 | #else
|
|---|
| 957 | err = setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one));
|
|---|
| 958 | #endif /* BSD42 */
|
|---|
| 959 | if (err < 0)
|
|---|
| 960 | sockets_err("setsockopt");
|
|---|
| 961 | }
|
|---|
| 962 | fromlen = sizeof(frominet);
|
|---|
| 963 | domain = AF_INET;
|
|---|
| 964 | if (timeout > 0) {
|
|---|
| 965 | fd_set readfds, exceptfds;
|
|---|
| 966 | struct timeval tv_timeout;
|
|---|
| 967 | int n;
|
|---|
| 968 |
|
|---|
| 969 | tv_timeout.tv_sec = timeout/1000;
|
|---|
| 970 | tv_timeout.tv_usec = (timeout%1000)*1000;
|
|---|
| 971 |
|
|---|
| 972 | FD_ZERO(&readfds);
|
|---|
| 973 | FD_ZERO(&exceptfds);
|
|---|
| 974 | FD_SET(fd, &readfds);
|
|---|
| 975 | FD_SET(fd, &exceptfds);
|
|---|
| 976 |
|
|---|
| 977 | n = select( fd+1, &readfds, NULL, &exceptfds, &tv_timeout );
|
|---|
| 978 | if (n == 0 || n == SOCKET_ERROR) {
|
|---|
| 979 | sockets_err("select listen");
|
|---|
| 980 | return 0;
|
|---|
| 981 | }
|
|---|
| 982 | }
|
|---|
| 983 | if((fd=accept(fd, SOCKADDR_CAST &frominet, &fromlen) ) < 0)
|
|---|
| 984 | sockets_err("accept");
|
|---|
| 985 |
|
|---|
| 986 | if (getpeername(fd, SOCKADDR_CAST &peer, &peerlen) < 0)
|
|---|
| 987 | sockets_err("getpeername");
|
|---|
| 988 |
|
|---|
| 989 | fprintf(stderr,"ttcp-r: accept from %s\n",inet_ntoa(peer.sin_addr));
|
|---|
| 990 |
|
|---|
| 991 | } /* otherwise we are ... */
|
|---|
| 992 | }
|
|---|
| 993 |
|
|---|
| 994 | prep_timer();
|
|---|
| 995 | errno = 0;
|
|---|
| 996 | nbytes = 0.0;
|
|---|
| 997 | numCalls = 0;
|
|---|
| 998 |
|
|---|
| 999 | {
|
|---|
| 1000 | register int cnt,multi;
|
|---|
| 1001 | char *pb;
|
|---|
| 1002 | int nb = 0;
|
|---|
| 1003 | unsigned long rbuflen = 0;
|
|---|
| 1004 | multi = nbuf;
|
|---|
| 1005 |
|
|---|
| 1006 | if (trans) {
|
|---|
| 1007 | #if !defined(BSD43)
|
|---|
| 1008 | if(udp) {
|
|---|
| 1009 | int err;
|
|---|
| 1010 | int nochecksum_opt = 0;
|
|---|
| 1011 | err = setsockopt(fd, IPPROTO_UDP, UDP_NOCHECKSUM,
|
|---|
| 1012 | (char *)&nochecksum_opt, sizeof(nochecksum_opt));
|
|---|
| 1013 | if (err < 0)
|
|---|
| 1014 | sockets_err("setsockopt");
|
|---|
| 1015 | }
|
|---|
| 1016 | #endif
|
|---|
| 1017 |
|
|---|
| 1018 | if(udp && !no_start) {
|
|---|
| 1019 | int start_count = 2;
|
|---|
| 1020 | char start_pkt[START_PKT_LEN];
|
|---|
| 1021 | memset(start_pkt, 0, START_PKT_LEN);
|
|---|
| 1022 | memcpy(start_pkt, start_pattern, START_PATTERN_LEN);
|
|---|
| 1023 |
|
|---|
| 1024 | while (start_count-- > 0) {
|
|---|
| 1025 | (void)Nwrite( fd, start_pkt, START_PKT_LEN ); /* rcvr start */
|
|---|
| 1026 | if (udpsleep) {
|
|---|
| 1027 | usleep(udpsleep);
|
|---|
| 1028 | /* clear errno (see man page for errno(3), definition of
|
|---|
| 1029 | EINTR. usleep() uses SIGCONT? ) */
|
|---|
| 1030 | if (errno == EINTR) errno = 0;
|
|---|
| 1031 | } /* udpsleep */
|
|---|
| 1032 | }
|
|---|
| 1033 | }
|
|---|
| 1034 |
|
|---|
| 1035 | /* initial seqence num for UDP */
|
|---|
| 1036 | if (udp) buf[0] = 0;
|
|---|
| 1037 | k = burstn;
|
|---|
| 1038 |
|
|---|
| 1039 | if (sinkmode) {
|
|---|
| 1040 | while (multi-- > 0 && !no_data) {
|
|---|
| 1041 |
|
|---|
| 1042 | if (bufmin == -1) {
|
|---|
| 1043 | rbuflen = buflen;
|
|---|
| 1044 | } else {
|
|---|
| 1045 | /* set rbuflen to a random value evenly distributed in
|
|---|
| 1046 | [bufmin, buflen]. As long as buflen is < 2^16, we can
|
|---|
| 1047 | fit the calculation in 32 bits */
|
|---|
| 1048 | #if defined(__NTVIS__)
|
|---|
| 1049 | rbuflen = (( (unsigned long)rand() *
|
|---|
| 1050 | ((unsigned long)(buflen-bufmin+1)) ) >> 15) + bufmin;
|
|---|
| 1051 | #else /* ! __NTVIS__ */
|
|---|
| 1052 | rbuflen = (( ((unsigned long)random() >> 15) *
|
|---|
| 1053 | ((unsigned long)(buflen-bufmin+1)) ) >> 16) + bufmin;
|
|---|
| 1054 | #endif /* __NTVIS__ */
|
|---|
| 1055 | }
|
|---|
| 1056 |
|
|---|
| 1057 | if (rndm) {
|
|---|
| 1058 | unsigned int i, j, l;
|
|---|
| 1059 | unsigned long data;
|
|---|
| 1060 |
|
|---|
| 1061 | if (udp)
|
|---|
| 1062 | l = 1;
|
|---|
| 1063 | else
|
|---|
| 1064 | l = 0;
|
|---|
| 1065 |
|
|---|
| 1066 | for (i = l; i < rbuflen; /* null */) {
|
|---|
| 1067 | #if defined(__NTVIS__)
|
|---|
| 1068 | data = (unsigned long)rand();
|
|---|
| 1069 | #else /* ! __NTVIS__ */
|
|---|
| 1070 | data = (unsigned long)random();
|
|---|
| 1071 | #endif /* __NTVIS__ */
|
|---|
| 1072 | /*fprintf(stderr, "%08x\n",data);*/ /* DEBUG */
|
|---|
| 1073 | /* The NT rand() function returns only 16 useful bits! */
|
|---|
| 1074 | for (j = 0; (j < 2/*4*/) && (i < rbuflen) ; j++) {
|
|---|
| 1075 | buf[i++] = (unsigned char)(data & 0xff);
|
|---|
| 1076 | data >>= 8;
|
|---|
| 1077 | }
|
|---|
| 1078 | }
|
|---|
| 1079 | }
|
|---|
| 1080 |
|
|---|
| 1081 | if ((cnt=Nwrite(fd,buf,rbuflen)) != (int)rbuflen)
|
|---|
| 1082 | sockets_err("error from the socket write");
|
|---|
| 1083 | /* increment sequence num if UDP */
|
|---|
| 1084 | if (udp) buf[0] = (char)(((unsigned char)(buf[0])+1) & 0xFF);
|
|---|
| 1085 |
|
|---|
| 1086 | if (debug)
|
|---|
| 1087 | fprintf(stdout,"ttcp-t: %5d | %d Bytes Written in %d write commands \n",
|
|---|
| 1088 | ++nb, cnt, nbuf );
|
|---|
| 1089 |
|
|---|
| 1090 | nbytes += rbuflen;
|
|---|
| 1091 |
|
|---|
| 1092 | /* hashes */
|
|---|
| 1093 | if (hash) {
|
|---|
| 1094 | fprintf(stderr,"#");
|
|---|
| 1095 | }
|
|---|
| 1096 |
|
|---|
| 1097 | /* Check for the end of a burst */
|
|---|
| 1098 | if (--k <= 0) {
|
|---|
| 1099 | k = burstn;
|
|---|
| 1100 |
|
|---|
| 1101 | /* sleep to avoid overrunning slower receivers - henry */
|
|---|
| 1102 | if (udpsleep) {
|
|---|
| 1103 | usleep(udpsleep);
|
|---|
| 1104 | /* clear errno (see man page for errno(3), definition of
|
|---|
| 1105 | EINTR. usleep() uses SIGCONT? ) */
|
|---|
| 1106 | if (errno == EINTR) errno = 0;
|
|---|
| 1107 | } /* udpsleep */
|
|---|
| 1108 | }
|
|---|
| 1109 | } /* while */
|
|---|
| 1110 |
|
|---|
| 1111 | } /* if (sinkmode) */
|
|---|
| 1112 | else
|
|---|
| 1113 | {
|
|---|
| 1114 |
|
|---|
| 1115 | nbuf = 0;
|
|---|
| 1116 |
|
|---|
| 1117 | if (bufmin == -1) {
|
|---|
| 1118 | rbuflen = buflen;
|
|---|
| 1119 | } else {
|
|---|
| 1120 | /* set rbuflen to a random value evenly distributed in
|
|---|
| 1121 | [bufmin, buflen]. As long as buflen is < 2^16, we can
|
|---|
| 1122 | fit the calculation in 32 bits */
|
|---|
| 1123 | #if defined(__NTVIS__)
|
|---|
| 1124 | rbuflen = (( (unsigned long)rand() *
|
|---|
| 1125 | ((unsigned long)(buflen-bufmin+1)) ) >> 15) + bufmin;
|
|---|
| 1126 | #else /* ! __NTVIS__ */
|
|---|
| 1127 | rbuflen = (( ((unsigned long)random() >> 15) *
|
|---|
| 1128 | ((unsigned long)(buflen-bufmin+1)) ) >> 16) + bufmin;
|
|---|
| 1129 | #endif /* __NTVIS__ */
|
|---|
| 1130 | }
|
|---|
| 1131 |
|
|---|
| 1132 | if (udp)
|
|---|
| 1133 | pb = &(buf[1]);
|
|---|
| 1134 | else
|
|---|
| 1135 | pb = &(buf[0]);
|
|---|
| 1136 |
|
|---|
| 1137 | #if !defined(__NTVIS__) /* else case specific to WINNT */
|
|---|
| 1138 | while((cnt=read(0,pb,rbuflen)) > 0)
|
|---|
| 1139 | #else /* __NTVIS__ */
|
|---|
| 1140 | while((cnt=(int)fread(pb,1,rbuflen,stdin)) > 0)
|
|---|
| 1141 | #endif /* __NTVIS__ */
|
|---|
| 1142 | {
|
|---|
| 1143 |
|
|---|
| 1144 | if (udp)
|
|---|
| 1145 | multi = cnt+1; /* don't include seq. num. in count of data */
|
|---|
| 1146 | else
|
|---|
| 1147 | multi = cnt;
|
|---|
| 1148 | if ((cnt=Nwrite(fd,buf,multi)) != (int)multi)
|
|---|
| 1149 | sockets_err("error from the socket write");
|
|---|
| 1150 | /* increment seqence num if UDP */
|
|---|
| 1151 | if (udp) buf[0] = (char)(((unsigned char)(buf[0])+1) & 0xFF);
|
|---|
| 1152 | nbuf++;
|
|---|
| 1153 |
|
|---|
| 1154 | if (debug)
|
|---|
| 1155 | fprintf(stdout,"ttcp-t: %5d | %d Bytes Written in %d write commands \n",
|
|---|
| 1156 | ++nb, cnt, nbuf );
|
|---|
| 1157 |
|
|---|
| 1158 | nbytes += multi;
|
|---|
| 1159 |
|
|---|
| 1160 | /* hashes */
|
|---|
| 1161 | if (hash) {
|
|---|
| 1162 | fprintf(stderr,"#");
|
|---|
| 1163 | }
|
|---|
| 1164 |
|
|---|
| 1165 | /* Check for the end of a burst */
|
|---|
| 1166 | if (--k <= 0) {
|
|---|
| 1167 | k = burstn;
|
|---|
| 1168 |
|
|---|
| 1169 | /* sleep to avoid overrunning slower receivers - henry */
|
|---|
| 1170 | if (udpsleep) {
|
|---|
| 1171 | usleep(udpsleep);
|
|---|
| 1172 | /* clear errno (see man page for errno(3), definition of
|
|---|
| 1173 | EINTR. usleep() uses SIGCONT? ) */
|
|---|
| 1174 | if (errno == EINTR) errno = 0;
|
|---|
| 1175 | } /* udpsleep */
|
|---|
| 1176 | }
|
|---|
| 1177 |
|
|---|
| 1178 | if (bufmin == -1) {
|
|---|
| 1179 | rbuflen = buflen;
|
|---|
| 1180 | } else {
|
|---|
| 1181 | /* set rbuflen to a random value evenly distributed in
|
|---|
| 1182 | [bufmin, buflen]. As long as buflen is < 2^16, we can
|
|---|
| 1183 | fit the calculation in 32 bits */
|
|---|
| 1184 | #if defined(__NTVIS__)
|
|---|
| 1185 | rbuflen = (( (unsigned long)rand() *
|
|---|
| 1186 | ((unsigned long)(buflen-bufmin+1)) ) >> 15) + bufmin;
|
|---|
| 1187 | #else /* ! __NTVIS__ */
|
|---|
| 1188 | rbuflen = (( ((unsigned long)random() >> 15) *
|
|---|
| 1189 | ((unsigned long)(buflen-bufmin+1)) ) >> 16) + bufmin;
|
|---|
| 1190 | #endif /* __NTVIS__ */
|
|---|
| 1191 | }
|
|---|
| 1192 |
|
|---|
| 1193 | } /* while */
|
|---|
| 1194 |
|
|---|
| 1195 | } /* if (sinkmode) */
|
|---|
| 1196 |
|
|---|
| 1197 | if (hash) {
|
|---|
| 1198 | fprintf(stderr,"\n");
|
|---|
| 1199 | fflush(stderr);
|
|---|
| 1200 | }
|
|---|
| 1201 |
|
|---|
| 1202 | #if defined(UNDER_CE)
|
|---|
| 1203 | errno = WSAGetLastError();
|
|---|
| 1204 | #endif
|
|---|
| 1205 | if (!errno) {
|
|---|
| 1206 | read_timer();
|
|---|
| 1207 | if(udp && !no_end) {
|
|---|
| 1208 | int end_count = 4;
|
|---|
| 1209 | int data_count = nbuf;
|
|---|
| 1210 | char end_pkt[END_PKT_LEN];
|
|---|
| 1211 | unsigned char* net_byte = &end_pkt[END_PATTERN_LEN];
|
|---|
| 1212 | memset(end_pkt, 0, END_PKT_LEN);
|
|---|
| 1213 | memcpy(end_pkt, end_pattern, END_PATTERN_LEN);
|
|---|
| 1214 | net_byte[3] = data_count & 0xFF; data_count >>= 8;
|
|---|
| 1215 | net_byte[2] = data_count & 0xFF; data_count >>= 8;
|
|---|
| 1216 | net_byte[1] = data_count & 0xFF; data_count >>= 8;
|
|---|
| 1217 | net_byte[0] = data_count & 0xFF;
|
|---|
| 1218 |
|
|---|
| 1219 | while (end_count-- > 0) {
|
|---|
| 1220 | Nwrite( fd, end_pkt, END_PKT_LEN ); /* rcvr end */
|
|---|
| 1221 | if (udpsleep && end_count>0) usleep(udpsleep);
|
|---|
| 1222 | }
|
|---|
| 1223 | }
|
|---|
| 1224 | result_summary();
|
|---|
| 1225 | }
|
|---|
| 1226 | } /* trans */
|
|---|
| 1227 | else
|
|---|
| 1228 | {
|
|---|
| 1229 | if (udp) {
|
|---|
| 1230 | udp_rcv_test();
|
|---|
| 1231 | }
|
|---|
| 1232 | else
|
|---|
| 1233 | {/* not udp received transfer */
|
|---|
| 1234 | while ((cnt=Nread(fd,buf,buflen)) > 0)
|
|---|
| 1235 | {if(debug)fprintf(stdout,
|
|---|
| 1236 | "ttcp%s: %5d | %d Bytes Read\n",
|
|---|
| 1237 | trans?"-t":"-r", ++nb, cnt );
|
|---|
| 1238 | nbytes += cnt;
|
|---|
| 1239 | if (!sinkmode) {
|
|---|
| 1240 | #if !defined(__NTVIS__) /* else case specific to WINNT */
|
|---|
| 1241 | if (write(1,buf,cnt) != cnt) err("write");
|
|---|
| 1242 | #else /* __NTVIS__ */
|
|---|
| 1243 | if ((int)fwrite(buf,1,cnt,stdout) != cnt) err("fwrite");
|
|---|
| 1244 | #endif /* __NTVIS__ */
|
|---|
| 1245 | }
|
|---|
| 1246 | }
|
|---|
| 1247 | #if defined(UNDER_CE)
|
|---|
| 1248 | errno = WSAGetLastError();
|
|---|
| 1249 | #endif
|
|---|
| 1250 | if (!errno) {
|
|---|
| 1251 | read_timer();
|
|---|
| 1252 | result_summary();
|
|---|
| 1253 | }
|
|---|
| 1254 | }
|
|---|
| 1255 | }
|
|---|
| 1256 | }
|
|---|
| 1257 |
|
|---|
| 1258 | if(errno) err("IO");
|
|---|
| 1259 |
|
|---|
| 1260 | #if defined(__NTVIS__)
|
|---|
| 1261 | closesocket ( fd );
|
|---|
| 1262 | #else
|
|---|
| 1263 | close ( fd );
|
|---|
| 1264 | #endif /* __NTVIS__ */
|
|---|
| 1265 |
|
|---|
| 1266 | if (verbose) fprintf(stdout,"ttcp%s: File-Descriptor fd 0x%x Closed\n" ,
|
|---|
| 1267 | trans?"-t":"-r", fd );
|
|---|
| 1268 |
|
|---|
| 1269 | if (log_cnt) close_log();
|
|---|
| 1270 |
|
|---|
| 1271 | fprintf(stderr,"ttcp done.\n");
|
|---|
| 1272 | fflush(stdout);
|
|---|
| 1273 |
|
|---|
| 1274 | exit(0);
|
|---|
| 1275 | }
|
|---|
| 1276 | /*--------------------------------------------------------------------------*/
|
|---|
| 1277 | void
|
|---|
| 1278 | udp_rcv_test(void)
|
|---|
| 1279 | {
|
|---|
| 1280 | enum {START_WAIT, DATA_WAIT, DATA_RCV, END_TEST} rcv_state;
|
|---|
| 1281 | enum {START_PKT_TYPE, END_PKT_TYPE, DATA_PKT_TYPE} pkt_type;
|
|---|
| 1282 | int cnt;
|
|---|
| 1283 | int nbuffers = 0;
|
|---|
| 1284 | unsigned int start_pkt_cnt = 0;
|
|---|
| 1285 | unsigned int end_pkt_cnt = 0;
|
|---|
| 1286 | unsigned int data_pkt_cnt = 0;
|
|---|
| 1287 | unsigned int expected_pkt_cnt = 0;
|
|---|
| 1288 | unsigned char seq = 0;
|
|---|
| 1289 | unsigned char buf_seq;
|
|---|
| 1290 |
|
|---|
| 1291 | rcv_state = START_WAIT;
|
|---|
| 1292 | while (rcv_state != END_TEST && (cnt=Nread(fd,buf,buflen)) > 0) {
|
|---|
| 1293 | /* Determine the type of packet received */
|
|---|
| 1294 | if (!memcmp(buf, start_pattern, START_PATTERN_LEN)) {
|
|---|
| 1295 | pkt_type = START_PKT_TYPE;
|
|---|
| 1296 | start_pkt_cnt++;
|
|---|
| 1297 | } else if (!memcmp(buf, end_pattern, END_PATTERN_LEN)) {
|
|---|
| 1298 | /* read the expected data packet count from the end packet */
|
|---|
| 1299 | unsigned char* net_byte = buf;
|
|---|
| 1300 | net_byte += END_PATTERN_LEN;
|
|---|
| 1301 | expected_pkt_cnt = ((net_byte[0] << 24) + (net_byte[1] << 16) +
|
|---|
| 1302 | (net_byte[2] << 8) + net_byte[3]);
|
|---|
| 1303 | pkt_type = END_PKT_TYPE;
|
|---|
| 1304 | end_pkt_cnt++;
|
|---|
| 1305 | } else {
|
|---|
| 1306 | data_pkt_cnt++;
|
|---|
| 1307 | pkt_type = DATA_PKT_TYPE;
|
|---|
| 1308 | }
|
|---|
| 1309 |
|
|---|
| 1310 | if (rcv_state == START_WAIT) {
|
|---|
| 1311 | /* Wait until we see a vaild start packet */
|
|---|
| 1312 | if (pkt_type == START_PKT_TYPE) {
|
|---|
| 1313 | prep_timer();
|
|---|
| 1314 | rcv_state = DATA_WAIT;
|
|---|
| 1315 | } else if (pkt_type == DATA_PKT_TYPE) {
|
|---|
| 1316 | fprintf(stderr, "ERROR: Missed UDP start packet.\n");
|
|---|
| 1317 | prep_timer();
|
|---|
| 1318 | rcv_state = DATA_RCV;
|
|---|
| 1319 | } else if (pkt_type == END_PKT_TYPE) {
|
|---|
| 1320 | fprintf(stderr, "ERROR: Found UDP end packet before start packet or data.\n");
|
|---|
| 1321 | rcv_state = END_TEST;
|
|---|
| 1322 | }
|
|---|
| 1323 | } else if (rcv_state == DATA_WAIT) {
|
|---|
| 1324 | /* Skip any extra start packets until we see data */
|
|---|
| 1325 | if (pkt_type == START_PKT_TYPE) {
|
|---|
| 1326 | prep_timer();
|
|---|
| 1327 | } else if (pkt_type == DATA_PKT_TYPE) {
|
|---|
| 1328 | rcv_state = DATA_RCV;
|
|---|
| 1329 | } else if (pkt_type == END_PKT_TYPE) {
|
|---|
| 1330 | fprintf(stderr, "ERROR: Found UDP end packet without receiving "
|
|---|
| 1331 | "any data packets.\n");
|
|---|
| 1332 | rcv_state = END_TEST;
|
|---|
| 1333 | }
|
|---|
| 1334 | } else { /* DATA_RCV */
|
|---|
| 1335 | /* Collect data packets until we see a vaild end packet */
|
|---|
| 1336 | if (pkt_type == START_PKT_TYPE) {
|
|---|
| 1337 | /* We missed the end packets and now a new test is
|
|---|
| 1338 | * starting. Report the results of this test then start
|
|---|
| 1339 | * another. */
|
|---|
| 1340 | read_timer();
|
|---|
| 1341 | result_summary();
|
|---|
| 1342 | fprintf(stderr, "ERROR: Found UDP start packet while receiving data.\n"
|
|---|
| 1343 | "ERROR: Expected more data packets or an end packet.\n");
|
|---|
| 1344 | nbytes = 0.0;
|
|---|
| 1345 | nbuffers = 0;
|
|---|
| 1346 | numCalls = 0;
|
|---|
| 1347 | prep_timer();
|
|---|
| 1348 | rcv_state = DATA_WAIT;
|
|---|
| 1349 | } else if (pkt_type == DATA_PKT_TYPE) {
|
|---|
| 1350 | /* loop in this state */
|
|---|
| 1351 | } else if (pkt_type == END_PKT_TYPE) {
|
|---|
| 1352 | /* we used to print results here but now we do when the loop ends */
|
|---|
| 1353 | rcv_state = END_TEST;
|
|---|
| 1354 | }
|
|---|
| 1355 | }
|
|---|
| 1356 |
|
|---|
| 1357 | /* tally data packets the same way from whatever state we are in */
|
|---|
| 1358 | if (pkt_type == DATA_PKT_TYPE) {
|
|---|
| 1359 | if (debug)
|
|---|
| 1360 | fprintf(stderr, "ttcp-r: %5d | %d Bytes Read\n", ++nbuffers, cnt);
|
|---|
| 1361 | nbytes += cnt;
|
|---|
| 1362 | if (seq_info) {
|
|---|
| 1363 | /* check seqence num */
|
|---|
| 1364 | buf_seq = (unsigned char)(buf[0]);
|
|---|
| 1365 | if (buf_seq != seq) {
|
|---|
| 1366 | fprintf(stderr, "ERROR: Out of sequence. "
|
|---|
| 1367 | "Buffer %u, seq %u, expected %u\n",
|
|---|
| 1368 | data_pkt_cnt, buf_seq, seq);
|
|---|
| 1369 | seq = buf_seq;
|
|---|
| 1370 | }
|
|---|
| 1371 | seq++;
|
|---|
| 1372 | }
|
|---|
| 1373 | if (!sinkmode) {
|
|---|
| 1374 | #if !defined(__NTVIS__) /* else case specific to WINNT */
|
|---|
| 1375 | if (write(1,&(buf[1]),cnt-1) != cnt-1) err("write");
|
|---|
| 1376 | #else /* __NTVIS__ */
|
|---|
| 1377 | if ((int)fwrite(&(buf[1]),1,cnt-1,stdout) != cnt-1) err("fwrite");
|
|---|
| 1378 | #endif /* __NTVIS__ */
|
|---|
| 1379 | }
|
|---|
| 1380 | }
|
|---|
| 1381 | } /* end-while */
|
|---|
| 1382 |
|
|---|
| 1383 | /* normal end of test */
|
|---|
| 1384 | read_timer();
|
|---|
| 1385 | result_summary();
|
|---|
| 1386 | fprintf(stderr, "ttcp-r: packets %u data, %u start, %u end\n",
|
|---|
| 1387 | data_pkt_cnt, start_pkt_cnt, end_pkt_cnt);
|
|---|
| 1388 | if (expected_pkt_cnt != 0) {
|
|---|
| 1389 | int lost_cnt = expected_pkt_cnt - data_pkt_cnt;
|
|---|
| 1390 |
|
|---|
| 1391 | fprintf(stderr, "ttcp-r: %g%% (%u/%u) packet loss\n",
|
|---|
| 1392 | 100.0 * (double)lost_cnt/(double)expected_pkt_cnt,
|
|---|
| 1393 | lost_cnt, expected_pkt_cnt);
|
|---|
| 1394 | }
|
|---|
| 1395 | }
|
|---|
| 1396 |
|
|---|
| 1397 | /*--------------------------------------------------------------------------*/
|
|---|
| 1398 | /* calc_cpu_time(): Time difference, in usecs, of the combined user and
|
|---|
| 1399 | * sys times of the given start and end usage info */
|
|---|
| 1400 | double
|
|---|
| 1401 | calc_cpu_time(
|
|---|
| 1402 | struct rusage *r0,
|
|---|
| 1403 | struct rusage *r1
|
|---|
| 1404 | )
|
|---|
| 1405 | {
|
|---|
| 1406 | double time;
|
|---|
| 1407 | time_t ms;
|
|---|
| 1408 | struct timeval tdiff, tend, tstart;
|
|---|
| 1409 |
|
|---|
| 1410 | /* total user delta time + total system delta time */
|
|---|
| 1411 | tvadd( &tend, &r1->ru_utime, &r1->ru_stime ); /* user + sys time @ end */
|
|---|
| 1412 | tvadd( &tstart, &r0->ru_utime, &r0->ru_stime ); /* user + sys time @ start*/
|
|---|
| 1413 | tvsub( &tdiff, &tend, &tstart );
|
|---|
| 1414 |
|
|---|
| 1415 | /* useconds */
|
|---|
| 1416 | time = ((double)tdiff.tv_sec)*1e6 + (double)tdiff.tv_usec;
|
|---|
| 1417 |
|
|---|
| 1418 | /* debug mseconds */
|
|---|
| 1419 | ms = tdiff.tv_sec*(time_t)1000 + tdiff.tv_usec/(time_t)1000;
|
|---|
| 1420 | if (ms != (time_t)(time/1000.0)) {
|
|---|
| 1421 | fprintf(stderr, "ERROR: time calc mismatch of msec (%d) to usec (%f)\n",
|
|---|
| 1422 | (int)ms, time/1000.0);
|
|---|
| 1423 | }
|
|---|
| 1424 |
|
|---|
| 1425 | return time;
|
|---|
| 1426 | }
|
|---|
| 1427 |
|
|---|
| 1428 | /*--------------------------------------------------------------------------*/
|
|---|
| 1429 | /* calc_real_time(): Time difference in usecs of the given times */
|
|---|
| 1430 | double
|
|---|
| 1431 | calc_real_time(
|
|---|
| 1432 | struct timeval *t0,
|
|---|
| 1433 | struct timeval *t1
|
|---|
| 1434 | )
|
|---|
| 1435 | {
|
|---|
| 1436 | double time;
|
|---|
| 1437 | time_t ms;
|
|---|
| 1438 | struct timeval tdiff;
|
|---|
| 1439 |
|
|---|
| 1440 | tvsub(&tdiff, t1 ,t0);
|
|---|
| 1441 |
|
|---|
| 1442 | /* useconds */
|
|---|
| 1443 | time = ((double)tdiff.tv_sec)*1e6 + (double)tdiff.tv_usec;
|
|---|
| 1444 |
|
|---|
| 1445 | /* debug mseconds */
|
|---|
| 1446 | ms = tdiff.tv_sec*(time_t)1000 + tdiff.tv_usec/(time_t)1000;
|
|---|
| 1447 | if (ms != (time_t)(time/1000.0)) {
|
|---|
| 1448 | fprintf(stderr, "ERROR: time calc mismatch of msec (%d) to usec (%f)\n",
|
|---|
| 1449 | (int)ms, time/1000.0);
|
|---|
| 1450 | }
|
|---|
| 1451 |
|
|---|
| 1452 | return time;
|
|---|
| 1453 | }
|
|---|
| 1454 | /*--------------------------------------------------------------------------*/
|
|---|
| 1455 | void
|
|---|
| 1456 | result_summary(void)
|
|---|
| 1457 | {
|
|---|
| 1458 | char* label = trans ? "ttcp-t" : "ttcp-r";
|
|---|
| 1459 | double cput = calc_cpu_time(&ru0, &ru1);
|
|---|
| 1460 | double realt = calc_real_time(&time0, &time1);
|
|---|
| 1461 | double t_min;
|
|---|
| 1462 | double bytes_per_sec;
|
|---|
| 1463 |
|
|---|
| 1464 | /* lower end boundary conditions */
|
|---|
| 1465 | t_min = 10.0; /* 10 usec */
|
|---|
| 1466 | #if defined(__NTVIS__)
|
|---|
| 1467 | t_min = 1000.0; /* 1 msec */
|
|---|
| 1468 | #endif
|
|---|
| 1469 | if (cput <= t_min) { /* value in usec */
|
|---|
| 1470 | cput = t_min;
|
|---|
| 1471 | fprintf(stderr,"%s: cpu time too short set at %.0f usec, NOT accurate result.\n",
|
|---|
| 1472 | label,t_min);
|
|---|
| 1473 | }
|
|---|
| 1474 | if (realt <= t_min) { /* value in usec */
|
|---|
| 1475 | realt = t_min;
|
|---|
| 1476 | fprintf(stderr,"%s: real time too short, set at %.0f usec, NOT accurate result.\n",
|
|---|
| 1477 | label,t_min);
|
|---|
| 1478 | }
|
|---|
| 1479 |
|
|---|
| 1480 | bytes_per_sec = (nbytes/realt)*1e6;
|
|---|
| 1481 |
|
|---|
| 1482 | fprintf(stderr,"%s: %.0f bytes in %.06f real seconds = %s/sec +++\n",
|
|---|
| 1483 | label, nbytes, realt/1e6, outfmt(fmt, bytes_per_sec));
|
|---|
| 1484 |
|
|---|
| 1485 | if (verbose)
|
|---|
| 1486 | fprintf(stderr,"%s: %.0f bytes in %.06f cpu seconds = %s/cpu sec\n",
|
|---|
| 1487 | label, nbytes,cput/1e6, outfmt(fmt, (nbytes/cput)*1e6));
|
|---|
| 1488 |
|
|---|
| 1489 | fprintf(stderr,"%s: %ld I/O calls, %.3f msec(real)/call, %.3f msec(cpu)/call\n",
|
|---|
| 1490 | label, numCalls,
|
|---|
| 1491 | (numCalls>0)?(realt/(double)numCalls)/1000.0:0.0,
|
|---|
| 1492 | (numCalls>0)?(cput /(double)numCalls)/1000.0:0.0);
|
|---|
| 1493 |
|
|---|
| 1494 | fprintf(stderr,"%s: ", label);
|
|---|
| 1495 | prusage(&ru0, &ru1, &time0, &time1);
|
|---|
| 1496 | fprintf(stderr,"\n");
|
|---|
| 1497 |
|
|---|
| 1498 | if (verbose)
|
|---|
| 1499 | printf("%s: buffer address %#x\n", label, (unsigned int)buf);
|
|---|
| 1500 |
|
|---|
| 1501 | if (fplog) {
|
|---|
| 1502 | struct timeval tdiff;
|
|---|
| 1503 | /* User time */
|
|---|
| 1504 | tvsub(&tdiff, &ru1.ru_utime, &ru0.ru_utime);
|
|---|
| 1505 | fprintf(fplog," %ld.%06ld", (long)tdiff.tv_sec, (long)tdiff.tv_usec);
|
|---|
| 1506 | /* System time */
|
|---|
| 1507 | tvsub(&tdiff, &ru1.ru_stime, &ru0.ru_stime);
|
|---|
| 1508 | fprintf(fplog," %ld.%06ld", (long)tdiff.tv_sec, (long)tdiff.tv_usec);
|
|---|
| 1509 | /* Percent of cput usage */
|
|---|
| 1510 | fprintf(fplog," %.1f", 100.0 * (cput/realt));
|
|---|
| 1511 | /* validity of real time mesurment */
|
|---|
| 1512 | fprintf(fplog, (realt == t_min)?" 0":" 1");
|
|---|
| 1513 | /* bytes, seconds, MBytes/sec, IO calls */
|
|---|
| 1514 | fprintf(fplog," %10.0f %4.06f %4.3f %6ld",
|
|---|
| 1515 | nbytes, realt/1e6, bytes_per_sec/(1024.0*1024.0), numCalls);
|
|---|
| 1516 | }
|
|---|
| 1517 | }
|
|---|
| 1518 | /*--------------------------------------------------------------------------*/
|
|---|
| 1519 | void
|
|---|
| 1520 | sockets_err(char* s)
|
|---|
| 1521 | {
|
|---|
| 1522 | #if defined(__NTVIS__)
|
|---|
| 1523 | int err = WSAGetLastError();
|
|---|
| 1524 | char* prefix = trans?"ttcp-t":"ttcp-r";
|
|---|
| 1525 | fprintf(stderr,"%s: %s\n", prefix, s);
|
|---|
| 1526 | fprintf(stderr,"%s: errno=%d\n", prefix, err);
|
|---|
| 1527 | exit(1);
|
|---|
| 1528 | #else
|
|---|
| 1529 | err(s);
|
|---|
| 1530 | #endif /* __NTVIS__ */
|
|---|
| 1531 | }
|
|---|
| 1532 |
|
|---|
| 1533 | /*--------------------------------------------------------------------------*/
|
|---|
| 1534 | void
|
|---|
| 1535 | err(char *s)
|
|---|
| 1536 | {
|
|---|
| 1537 | char* prefix = trans?"ttcp-t":"ttcp-r";
|
|---|
| 1538 | fprintf(stderr,"%s: ", prefix);
|
|---|
| 1539 | perror(s);
|
|---|
| 1540 | fprintf(stderr,"%s: errno=%d\n", prefix, errno);
|
|---|
| 1541 | exit(1);
|
|---|
| 1542 | }
|
|---|
| 1543 | /*--------------------------------------------------------------------------*/
|
|---|
| 1544 | void
|
|---|
| 1545 | mes(char *s)
|
|---|
| 1546 | {
|
|---|
| 1547 | fprintf(stderr,"ttcp%s: %s\n", trans?"-t":"-r", s);
|
|---|
| 1548 | }
|
|---|
| 1549 | /*--------------------------------------------------------------------------*/
|
|---|
| 1550 | void
|
|---|
| 1551 | pattern( char *cp, int cnt )
|
|---|
| 1552 | {
|
|---|
| 1553 | register char c;
|
|---|
| 1554 | register int cnt1;
|
|---|
| 1555 | cnt1 = cnt;
|
|---|
| 1556 | c = 0;
|
|---|
| 1557 | while( cnt1-- > 0 ) {
|
|---|
| 1558 | while( !isprint((c&0x7F)) ) c++;
|
|---|
| 1559 | *cp++ = (c++&0x7F);
|
|---|
| 1560 | }
|
|---|
| 1561 | }
|
|---|
| 1562 | /*--------------------------------------------------------------------------*/
|
|---|
| 1563 | char *
|
|---|
| 1564 | outfmt(char format, double b)
|
|---|
| 1565 | {
|
|---|
| 1566 | static char obuf[50];
|
|---|
| 1567 | double giga = 1024.0 * 1024.0 * 1024.0;
|
|---|
| 1568 | double mega = 1024.0 * 1024.0;
|
|---|
| 1569 | double kilo = 1024.0;
|
|---|
| 1570 |
|
|---|
| 1571 | if (format == 'A') {
|
|---|
| 1572 | if (b >= giga)
|
|---|
| 1573 | format = 'G';
|
|---|
| 1574 | else if (b >= mega)
|
|---|
| 1575 | format = 'M';
|
|---|
| 1576 | else if (b >= kilo)
|
|---|
| 1577 | format = 'K';
|
|---|
| 1578 | else
|
|---|
| 1579 | format = 'B';
|
|---|
| 1580 | }
|
|---|
| 1581 |
|
|---|
| 1582 | switch (format) {
|
|---|
| 1583 | case 'G':
|
|---|
| 1584 | sprintf(obuf, "%.3f GB", b / giga);
|
|---|
| 1585 | break;
|
|---|
| 1586 | case 'M':
|
|---|
| 1587 | sprintf(obuf, "%.3f MB", b / mega);
|
|---|
| 1588 | break;
|
|---|
| 1589 | case 'K':
|
|---|
| 1590 | sprintf(obuf, "%.3f KB", b / kilo);
|
|---|
| 1591 | break;
|
|---|
| 1592 | case 'B':
|
|---|
| 1593 | sprintf(obuf, "%4f B", b);
|
|---|
| 1594 | break;
|
|---|
| 1595 | case 'g':
|
|---|
| 1596 | sprintf(obuf, "%.3f Gbit", b * 8.0 / giga);
|
|---|
| 1597 | break;
|
|---|
| 1598 | case 'm':
|
|---|
| 1599 | sprintf(obuf, "%.3f Mbit", b * 8.0 / mega);
|
|---|
| 1600 | break;
|
|---|
| 1601 | case 'k':
|
|---|
| 1602 | sprintf(obuf, "%.3f Kbit", b * 8.0 / kilo);
|
|---|
| 1603 | break;
|
|---|
| 1604 | case 'b':
|
|---|
| 1605 | sprintf(obuf, "%4f b", b * 8.0);
|
|---|
| 1606 | break;
|
|---|
| 1607 | default:
|
|---|
| 1608 | sprintf(obuf, "default..........");
|
|---|
| 1609 | }
|
|---|
| 1610 | return obuf;
|
|---|
| 1611 | }
|
|---|
| 1612 | /*--------------------------------------------------------------------------*/
|
|---|
| 1613 | #if defined(SYSV)
|
|---|
| 1614 |
|
|---|
| 1615 | /*ARGSUSED*/
|
|---|
| 1616 |
|
|---|
| 1617 | #if defined(__osf__)
|
|---|
| 1618 | /* getrusage defined in the system lib */
|
|---|
| 1619 | #else
|
|---|
| 1620 | #if defined(__lynx__)
|
|---|
| 1621 | /* getrusage defined in the system lib */
|
|---|
| 1622 | #else
|
|---|
| 1623 | #if defined(__sun__)
|
|---|
| 1624 | /* getrusage defined in the system lib */
|
|---|
| 1625 | #else
|
|---|
| 1626 |
|
|---|
| 1627 | int
|
|---|
| 1628 | getrusage(ignored, ru)
|
|---|
| 1629 | int ignored;
|
|---|
| 1630 | register struct rusage *ru;
|
|---|
| 1631 | {
|
|---|
| 1632 |
|
|---|
| 1633 |
|
|---|
| 1634 | #if defined(__NTVIS__)
|
|---|
| 1635 | HANDLE phd;
|
|---|
| 1636 | FILETIME CreateTime, ExitTime, KernelTime, UserTime;
|
|---|
| 1637 | SYSTEMTIME SysTime;
|
|---|
| 1638 | #if defined(UNDER_CE)
|
|---|
| 1639 | phd = GetCurrentThread();
|
|---|
| 1640 | if( GetThreadTimes(phd, &CreateTime, &ExitTime, &KernelTime, &UserTime)
|
|---|
| 1641 | != TRUE)
|
|---|
| 1642 | #else
|
|---|
| 1643 | phd = GetCurrentProcess();
|
|---|
| 1644 | if( GetProcessTimes(phd, &CreateTime, &ExitTime, &KernelTime, &UserTime)
|
|---|
| 1645 | != TRUE)
|
|---|
| 1646 | #endif
|
|---|
| 1647 | {ru->ru_stime.tv_sec = 0;
|
|---|
| 1648 | ru->ru_stime.tv_usec = 0;
|
|---|
| 1649 | ru->ru_utime.tv_sec = 0;
|
|---|
| 1650 | ru->ru_utime.tv_usec = 0;
|
|---|
| 1651 | }
|
|---|
| 1652 | else
|
|---|
| 1653 | {
|
|---|
| 1654 | (void) FileTimeToSystemTime(&KernelTime, &SysTime);
|
|---|
| 1655 | /*
|
|---|
| 1656 | * fprintf(stdout,
|
|---|
| 1657 | * "System sec=%d, msec=%d\n", SysTime.wSecond, SysTime.wMilliseconds);
|
|---|
| 1658 | */
|
|---|
| 1659 | ru->ru_stime.tv_sec = SysTime.wSecond;
|
|---|
| 1660 | ru->ru_stime.tv_usec = SysTime.wMilliseconds * 1000;
|
|---|
| 1661 | (void) FileTimeToSystemTime(&UserTime, &SysTime);
|
|---|
| 1662 | /*
|
|---|
| 1663 | * fprintf(stdout,
|
|---|
| 1664 | * " User sec=%d, msec=%d\n", SysTime.wSecond, SysTime.wMilliseconds);
|
|---|
| 1665 | */
|
|---|
| 1666 | ru->ru_utime.tv_sec = SysTime.wSecond;
|
|---|
| 1667 | ru->ru_utime.tv_usec = SysTime.wMilliseconds * 1000;
|
|---|
| 1668 | }
|
|---|
| 1669 |
|
|---|
| 1670 | #else /* __NTVIS__ */
|
|---|
| 1671 |
|
|---|
| 1672 | struct tms buftime;
|
|---|
| 1673 | times(&buftime);
|
|---|
| 1674 | /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */
|
|---|
| 1675 | /* info : in lynxOS HZ is called TICKSPERSEC (<conf.h>) */
|
|---|
| 1676 |
|
|---|
| 1677 | ru->ru_stime.tv_sec = buftime.tms_stime / HZ;
|
|---|
| 1678 | ru->ru_stime.tv_usec = ((buftime.tms_stime % HZ) * 1000000) / HZ;
|
|---|
| 1679 | ru->ru_utime.tv_sec = buftime.tms_utime / HZ;
|
|---|
| 1680 | ru->ru_utime.tv_usec = ((buftime.tms_utime % HZ) * 1000000) / HZ;
|
|---|
| 1681 | #endif /* __NTVIS__ */
|
|---|
| 1682 | return(0);
|
|---|
| 1683 |
|
|---|
| 1684 | } /* static getrusage */
|
|---|
| 1685 |
|
|---|
| 1686 | #endif /* __sun__ */
|
|---|
| 1687 | #endif /* __lynx__ */
|
|---|
| 1688 | #endif /* __osf__ */
|
|---|
| 1689 | #endif /* SYSV */
|
|---|
| 1690 | /*--------------------------------------------------------------------------*/
|
|---|
| 1691 | #if defined(SYSV)
|
|---|
| 1692 | #if defined(__hpux__) || defined(_AIX) || defined(__sun__)
|
|---|
| 1693 | /* gettimeofday defined in the system lib */
|
|---|
| 1694 | #else
|
|---|
| 1695 | # if defined (__osf__) ||defined (__lynx__)
|
|---|
| 1696 | /* gettimeofday defined in the system lib */
|
|---|
| 1697 | #else
|
|---|
| 1698 | /*ARGSUSED*/
|
|---|
| 1699 | static
|
|---|
| 1700 | gettimeofday(tp, zp)
|
|---|
| 1701 | struct timeval *tp;
|
|---|
| 1702 | struct timezone *zp;
|
|---|
| 1703 | {
|
|---|
| 1704 | #if defined(__NTVIS__)
|
|---|
| 1705 | #if defined(UNDER_CE)
|
|---|
| 1706 | SYSTEMTIME SystemTime;
|
|---|
| 1707 |
|
|---|
| 1708 | GetLocalTime(&SystemTime);
|
|---|
| 1709 | tp->tv_sec = SystemTime.wSecond;
|
|---|
| 1710 | tp->tv_usec = SystemTime.wMilliseconds * 1000;
|
|---|
| 1711 | #else
|
|---|
| 1712 | struct _timeb timeptr;
|
|---|
| 1713 |
|
|---|
| 1714 | _ftime(&timeptr);
|
|---|
| 1715 | tp->tv_sec = timeptr.time;
|
|---|
| 1716 | tp->tv_usec = timeptr.millitm * 1000;
|
|---|
| 1717 | #endif
|
|---|
| 1718 | #else /* all cases */
|
|---|
| 1719 | tp->tv_sec = time(0);
|
|---|
| 1720 | tp->tv_usec = 0;
|
|---|
| 1721 | #endif /* __NTVIS__ */
|
|---|
| 1722 | return(1);
|
|---|
| 1723 | } /* static gettimeofday */
|
|---|
| 1724 |
|
|---|
| 1725 | #endif /*__osf__ || __lynx__ */
|
|---|
| 1726 | #endif /* __hpux__ || _AIX || __sun__ || __osf__*/
|
|---|
| 1727 | #endif /* SYSV */
|
|---|
| 1728 | /*--------------------------------------------------------------------------*/
|
|---|
| 1729 | /*
|
|---|
| 1730 | * P R E P _ T I M E R
|
|---|
| 1731 | */
|
|---|
| 1732 | void
|
|---|
| 1733 | prep_timer(void)
|
|---|
| 1734 | {
|
|---|
| 1735 | gettimeofday(&time0, (struct timezone *)0);
|
|---|
| 1736 | getrusage(RUSAGE_SELF, &ru0);
|
|---|
| 1737 | }
|
|---|
| 1738 | /*--------------------------------------------------------------------------*/
|
|---|
| 1739 | /*
|
|---|
| 1740 | * R E A D _ T I M E R
|
|---|
| 1741 | *
|
|---|
| 1742 | */
|
|---|
| 1743 | void
|
|---|
| 1744 | read_timer(void)
|
|---|
| 1745 | {
|
|---|
| 1746 | getrusage(RUSAGE_SELF, &ru1);
|
|---|
| 1747 | gettimeofday(&time1, (struct timezone *)0);
|
|---|
| 1748 | }
|
|---|
| 1749 | /*--------------------------------------------------------------------------*/
|
|---|
| 1750 | /* Print the process usage calculated from timers values extracted
|
|---|
| 1751 | * before and after the transfer execution.
|
|---|
| 1752 | */
|
|---|
| 1753 | void
|
|---|
| 1754 | prusage(
|
|---|
| 1755 | struct rusage *r0, struct rusage *r1,
|
|---|
| 1756 | struct timeval *t0, struct timeval *t1
|
|---|
| 1757 | )
|
|---|
| 1758 | {
|
|---|
| 1759 | struct timeval tdiff;
|
|---|
| 1760 | int t, ms;
|
|---|
| 1761 | register char *cp;
|
|---|
| 1762 | double cput = calc_cpu_time(r0, r1);
|
|---|
| 1763 | double realt = calc_real_time(t0, t1);
|
|---|
| 1764 |
|
|---|
| 1765 | /* t == total user delta time + total system delta time */
|
|---|
| 1766 | if (debug)
|
|---|
| 1767 | {
|
|---|
| 1768 | printf("timers : end startup\n");
|
|---|
| 1769 | printf("user (sec) : %9ld %9ld\n",r1->ru_utime.tv_sec,
|
|---|
| 1770 | r0->ru_utime.tv_sec);
|
|---|
| 1771 | printf("user (usec): %9ld %9ld\n",r1->ru_utime.tv_usec,
|
|---|
| 1772 | r0->ru_utime.tv_usec);
|
|---|
| 1773 | printf("sys (sec) : %9ld %9ld\n",r1->ru_stime.tv_sec,
|
|---|
| 1774 | r0->ru_stime.tv_sec);
|
|---|
| 1775 | printf("sys (usec): %9ld %9ld\n",r1->ru_stime.tv_usec,
|
|---|
| 1776 | r0->ru_stime.tv_usec);
|
|---|
| 1777 | printf("time (sec) : %9ld %9ld\n",t1->tv_sec,t0->tv_sec);
|
|---|
| 1778 | printf("time (usec): %9ld %9ld\n",t1->tv_usec,t0->tv_usec);
|
|---|
| 1779 | }
|
|---|
| 1780 | /* for the AIX debug, most counters are outside a good range
|
|---|
| 1781 | printf(" r0 r1\n");
|
|---|
| 1782 | printf("ru_ixrss %20ld %20ld \n", r0->ru_ixrss ,r1->ru_ixrss );
|
|---|
| 1783 | printf("ru_idrss %20ld %20ld \n", r0->ru_idrss ,r1->ru_idrss );
|
|---|
| 1784 | printf("ru_isrss %20ld %20ld \n", r0->ru_isrss ,r1->ru_isrss );
|
|---|
| 1785 | printf("ru_minflt %20ld %20ld \n", r0->ru_minflt ,r1->ru_minflt );
|
|---|
| 1786 | printf("ru_majflt %20ld %20ld \n", r0->ru_majflt ,r1->ru_majflt );
|
|---|
| 1787 | printf("ru_nswap %20ld %20ld \n", r0->ru_nswap ,r1->ru_nswap );
|
|---|
| 1788 | printf("ru_inblock %20ld %20ld \n", r0->ru_inblock ,r1->ru_inblock );
|
|---|
| 1789 | printf("ru_oublock %20ld %20ld \n", r0->ru_oublock ,r1->ru_oublock );
|
|---|
| 1790 | printf("ru_msgsnd %20ld %20ld \n", r0->ru_msgsnd ,r1->ru_msgsnd );
|
|---|
| 1791 | printf("ru_msgrcv %20ld %20ld \n", r0->ru_msgrcv ,r1->ru_msgrcv );
|
|---|
| 1792 | printf("ru_nsignals %20ld %20ld \n", r0->ru_nsignals ,r1->ru_nsignals);
|
|---|
| 1793 | printf("ru_nvcsw %20ld %20ld \n", r0->ru_nvcsw ,r1->ru_nvcsw );
|
|---|
| 1794 | printf("ru_nivcsw %20ld %20ld \n", r0->ru_nivcsw ,r1->ru_nivcsw );
|
|---|
| 1795 | */
|
|---|
| 1796 |
|
|---|
| 1797 | /* cpu time in mseconds */
|
|---|
| 1798 | t = (int)(cput / 1000.0);
|
|---|
| 1799 |
|
|---|
| 1800 | /* ms == value of the internal clock at the end of the xfer */
|
|---|
| 1801 | /* also called real time. */
|
|---|
| 1802 | /* real time in mseconds */
|
|---|
| 1803 | ms = (int)(realt / 1000.0);
|
|---|
| 1804 |
|
|---|
| 1805 | /* The display is based on variables provided by the function getrusage
|
|---|
| 1806 | Info located in : /usr/include/sys/resource.h
|
|---|
| 1807 | */
|
|---|
| 1808 | #if defined(SYSV)
|
|---|
| 1809 |
|
|---|
| 1810 | #if defined(_AIX)
|
|---|
| 1811 | /* with AIX cernsp most counters are wrong
|
|---|
| 1812 | * cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw\0";
|
|---|
| 1813 | */
|
|---|
| 1814 | cp = "%Uuser %Ssys %Ereal %P\0";
|
|---|
| 1815 |
|
|---|
| 1816 | #else
|
|---|
| 1817 | #if defined(__osf__)
|
|---|
| 1818 | cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw\0";
|
|---|
| 1819 | #else
|
|---|
| 1820 | #if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */
|
|---|
| 1821 | cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw\0";
|
|---|
| 1822 | #else
|
|---|
| 1823 | #if defined(__Lynx__)
|
|---|
| 1824 | cp = "%Uuser %Ssys %Ereal %P\0";
|
|---|
| 1825 | #else
|
|---|
| 1826 | cp = "%Uuser %Ssys %Ereal %P\0"; /* all SYSV except those mentionned */
|
|---|
| 1827 | #endif /*__lynx__ */
|
|---|
| 1828 | #endif /* sgi */
|
|---|
| 1829 | #endif /*__osf__ */
|
|---|
| 1830 | #endif /* _AIX */
|
|---|
| 1831 |
|
|---|
| 1832 | #else /* BSD system */
|
|---|
| 1833 | cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw\0";
|
|---|
| 1834 |
|
|---|
| 1835 | #endif /* SYSV */
|
|---|
| 1836 |
|
|---|
| 1837 | for (; *cp; cp++) {
|
|---|
| 1838 | if (*cp != '%') {
|
|---|
| 1839 | putc(*cp, stderr);
|
|---|
| 1840 | /* *outp++ = *cp; */
|
|---|
| 1841 | } else if (cp[1])
|
|---|
| 1842 | switch(*++cp) {
|
|---|
| 1843 | case 'U':
|
|---|
| 1844 | tvsub(&tdiff, &r1->ru_utime, &r0->ru_utime);
|
|---|
| 1845 | fprintf(stderr,"%ld.%06ld", (long)tdiff.tv_sec, (long)tdiff.tv_usec);
|
|---|
| 1846 | break;
|
|---|
| 1847 |
|
|---|
| 1848 | case 'S':
|
|---|
| 1849 | tvsub(&tdiff, &r1->ru_stime, &r0->ru_stime);
|
|---|
| 1850 | fprintf(stderr,"%ld.%06ld", (long)tdiff.tv_sec, (long)tdiff.tv_usec);
|
|---|
| 1851 | break;
|
|---|
| 1852 |
|
|---|
| 1853 | case 'E':
|
|---|
| 1854 | psecs( ms / 1000);
|
|---|
| 1855 | break;
|
|---|
| 1856 |
|
|---|
| 1857 | case 'P':
|
|---|
| 1858 | fprintf(stderr,"%.1f%%", (cput*100.0 / (realt ? realt : 1.0)) );
|
|---|
| 1859 | break;
|
|---|
| 1860 |
|
|---|
| 1861 | #if !defined(SYSV) || defined(__osf__) || defined(_AIX)
|
|---|
| 1862 | case 'W':
|
|---|
| 1863 | {
|
|---|
| 1864 | int i = r1->ru_nswap - r0->ru_nswap;
|
|---|
| 1865 | fprintf(stderr,"%d", i);
|
|---|
| 1866 | break;
|
|---|
| 1867 | }
|
|---|
| 1868 |
|
|---|
| 1869 | case 'X':
|
|---|
| 1870 | fprintf(stderr,"%ld", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t);
|
|---|
| 1871 | break;
|
|---|
| 1872 |
|
|---|
| 1873 | case 'D':
|
|---|
| 1874 | fprintf(stderr,"%ld", t == 0 ? 0 :
|
|---|
| 1875 | (r1->ru_idrss+r1->ru_isrss - (r0->ru_idrss+r0->ru_isrss))/t);
|
|---|
| 1876 | break;
|
|---|
| 1877 |
|
|---|
| 1878 | case 'K':
|
|---|
| 1879 | fprintf(stderr,"%ld", t == 0 ? 0 :
|
|---|
| 1880 | ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) -
|
|---|
| 1881 | (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t);
|
|---|
| 1882 | break;
|
|---|
| 1883 |
|
|---|
| 1884 | case 'M':
|
|---|
| 1885 | fprintf(stderr,"%ld", r1->ru_maxrss/2);
|
|---|
| 1886 | break;
|
|---|
| 1887 |
|
|---|
| 1888 | case 'F':
|
|---|
| 1889 | fprintf(stderr,"%ld", r1->ru_majflt-r0->ru_majflt);
|
|---|
| 1890 | break;
|
|---|
| 1891 |
|
|---|
| 1892 | case 'R':
|
|---|
| 1893 | fprintf(stderr,"%ld", r1->ru_minflt-r0->ru_minflt);
|
|---|
| 1894 | break;
|
|---|
| 1895 |
|
|---|
| 1896 | case 'I':
|
|---|
| 1897 | fprintf(stderr,"%ld", r1->ru_inblock-r0->ru_inblock);
|
|---|
| 1898 | break;
|
|---|
| 1899 |
|
|---|
| 1900 | case 'O':
|
|---|
| 1901 | fprintf(stderr,"%ld", r1->ru_oublock-r0->ru_oublock);
|
|---|
| 1902 | break;
|
|---|
| 1903 |
|
|---|
| 1904 | case 'C':
|
|---|
| 1905 | fprintf(stderr,"%ld+%ld",
|
|---|
| 1906 | r1->ru_nvcsw-r0->ru_nvcsw, r1->ru_nivcsw-r0->ru_nivcsw);
|
|---|
| 1907 | break;
|
|---|
| 1908 | #endif /* !SYSV || __osf__ */
|
|---|
| 1909 | default:
|
|---|
| 1910 | putc(*cp, stderr);
|
|---|
| 1911 | break;
|
|---|
| 1912 | } /* switch */
|
|---|
| 1913 | } /* for */
|
|---|
| 1914 | }
|
|---|
| 1915 | /*--------------------------------------------------------------------------*/
|
|---|
| 1916 | /* add 2 times structure and move usec bigger than 1000000 to sec */
|
|---|
| 1917 | void
|
|---|
| 1918 | tvadd(tsum, t0, t1)
|
|---|
| 1919 | struct timeval *tsum, *t0, *t1;
|
|---|
| 1920 | {
|
|---|
| 1921 | tsum->tv_sec = t0->tv_sec + t1->tv_sec;
|
|---|
| 1922 | tsum->tv_usec = t0->tv_usec + t1->tv_usec;
|
|---|
| 1923 | if (tsum->tv_usec > 1000000) tsum->tv_sec++, tsum->tv_usec -= 1000000;
|
|---|
| 1924 | }
|
|---|
| 1925 | /*--------------------------------------------------------------------------*/
|
|---|
| 1926 | /* substract 2 time structure (t1 > t0) */
|
|---|
| 1927 | void
|
|---|
| 1928 | tvsub(tdiff, t1, t0)
|
|---|
| 1929 | struct timeval *tdiff, *t1, *t0;
|
|---|
| 1930 | {
|
|---|
| 1931 | tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
|
|---|
| 1932 | tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
|
|---|
| 1933 | if (tdiff->tv_usec < 0) tdiff->tv_sec--, tdiff->tv_usec += 1000000;
|
|---|
| 1934 | }
|
|---|
| 1935 |
|
|---|
| 1936 | /*--------------------------------------------------------------------------*/
|
|---|
| 1937 | void
|
|---|
| 1938 | psecs(int l)
|
|---|
| 1939 | {
|
|---|
| 1940 | int i = (int)l/3600;
|
|---|
| 1941 |
|
|---|
| 1942 | if (i) {
|
|---|
| 1943 | /* hours:min:sec */
|
|---|
| 1944 | fprintf(stderr,"%d:", i);
|
|---|
| 1945 | i = (int)l % 3600;
|
|---|
| 1946 | fprintf(stderr,"%.2d:%.2d", i/60, i%60);
|
|---|
| 1947 | } else {
|
|---|
| 1948 | /* min:sec */
|
|---|
| 1949 | i = (int)l;
|
|---|
| 1950 | fprintf(stderr,"%d:%.2d", i/60, i%60);
|
|---|
| 1951 | }
|
|---|
| 1952 | }
|
|---|
| 1953 | /*--------------------------------------------------------------------------*/
|
|---|
| 1954 | /* N R E A D */
|
|---|
| 1955 |
|
|---|
| 1956 | int
|
|---|
| 1957 | Nread(SOCKET s, void* bufp, int count )
|
|---|
| 1958 | {
|
|---|
| 1959 | #if defined(__lynx__) || defined(__svr4__) || defined(_AIX) || defined(__NTVIS__) || defined(__FreeBSD__)
|
|---|
| 1960 | struct sockaddr from;
|
|---|
| 1961 | #else
|
|---|
| 1962 | struct sockaddr_in from;
|
|---|
| 1963 | #endif
|
|---|
| 1964 | int len = sizeof(from);
|
|---|
| 1965 | register int cnt;
|
|---|
| 1966 |
|
|---|
| 1967 | if (timeout > 0) {
|
|---|
| 1968 | fd_set readfds, exceptfds;
|
|---|
| 1969 | struct timeval tv_timeout;
|
|---|
| 1970 | int n;
|
|---|
| 1971 |
|
|---|
| 1972 | tv_timeout.tv_sec = timeout/1000;
|
|---|
| 1973 | tv_timeout.tv_usec = (timeout%1000)*1000;
|
|---|
| 1974 |
|
|---|
| 1975 | FD_ZERO(&readfds);
|
|---|
| 1976 | FD_ZERO(&exceptfds);
|
|---|
| 1977 | FD_SET(s, &readfds);
|
|---|
| 1978 | FD_SET(s, &exceptfds);
|
|---|
| 1979 |
|
|---|
| 1980 | n = select( s+1, &readfds, NULL, &exceptfds, &tv_timeout );
|
|---|
| 1981 | if (n == SOCKET_ERROR) {
|
|---|
| 1982 | sockets_err("select read");
|
|---|
| 1983 | } else if (n == 0) {
|
|---|
| 1984 | return (0);
|
|---|
| 1985 | }
|
|---|
| 1986 |
|
|---|
| 1987 | }
|
|---|
| 1988 |
|
|---|
| 1989 | if( udp )
|
|---|
| 1990 | {cnt = recvfrom( s, bufp, count, 0, SOCKADDR_CAST &from, &len );
|
|---|
| 1991 | numCalls++;
|
|---|
| 1992 | }
|
|---|
| 1993 | else
|
|---|
| 1994 | {if( b_flag ) cnt = mread( s, bufp, count ); /* fill bufp */
|
|---|
| 1995 | else
|
|---|
| 1996 | {
|
|---|
| 1997 | #if defined(__NTVIS__)
|
|---|
| 1998 | cnt = recv( s, bufp, count, 0 );
|
|---|
| 1999 | #else
|
|---|
| 2000 | cnt = read( s, bufp, count );
|
|---|
| 2001 | #endif /* __NTVIS__ */
|
|---|
| 2002 | numCalls++;
|
|---|
| 2003 | }
|
|---|
| 2004 | if (touchdata && cnt > 0)
|
|---|
| 2005 | {register int c = cnt, sum = 0;
|
|---|
| 2006 | register char *b = bufp;
|
|---|
| 2007 | while (c--) sum += *b++;
|
|---|
| 2008 | }
|
|---|
| 2009 | }
|
|---|
| 2010 | /* rchrch printf (" numcall %d read buffer %d bytes \n",numCalls,cnt); */
|
|---|
| 2011 | return(cnt);
|
|---|
| 2012 | }
|
|---|
| 2013 | /*--------------------------------------------------------------------------*/
|
|---|
| 2014 | /* N W R I T E */
|
|---|
| 2015 |
|
|---|
| 2016 | int
|
|---|
| 2017 | Nwrite( int s, void* bufp, int count )
|
|---|
| 2018 | {
|
|---|
| 2019 | register int cnt;
|
|---|
| 2020 | if( udp )
|
|---|
| 2021 | {
|
|---|
| 2022 | again:
|
|---|
| 2023 | cnt = sendto( s, bufp, count, 0, SOCKADDR_CAST &sinhim,
|
|---|
| 2024 | sizeof(sinhim) );
|
|---|
| 2025 |
|
|---|
| 2026 | numCalls++;
|
|---|
| 2027 |
|
|---|
| 2028 | #if defined(__NTVIS__)
|
|---|
| 2029 | if( cnt<0 && WSAENOBUFS == WSAGetLastError())
|
|---|
| 2030 | #else
|
|---|
| 2031 | if( cnt<0 && errno == ENOBUFS )
|
|---|
| 2032 | #endif /* __NTVIS__ */
|
|---|
| 2033 |
|
|---|
| 2034 | { delay(18000); errno = 0; goto again; }
|
|---|
| 2035 | } else /* if (udp) */
|
|---|
| 2036 | {
|
|---|
| 2037 |
|
|---|
| 2038 | #if defined(__NTVIS__)
|
|---|
| 2039 | cnt = send( s, bufp, count, 0 );
|
|---|
| 2040 | numCalls++;
|
|---|
| 2041 | #else
|
|---|
| 2042 | cnt = write( s, bufp, count );
|
|---|
| 2043 | numCalls++;
|
|---|
| 2044 | #endif /* __NTVIS__ */
|
|---|
| 2045 | }
|
|---|
| 2046 | return(cnt);
|
|---|
| 2047 | }
|
|---|
| 2048 | /*--------------------------------------------------------------------------*/
|
|---|
| 2049 | void
|
|---|
| 2050 | delay(us)
|
|---|
| 2051 | int us;
|
|---|
| 2052 | {
|
|---|
| 2053 | struct timeval tv;
|
|---|
| 2054 |
|
|---|
| 2055 | tv.tv_sec = 0;
|
|---|
| 2056 | tv.tv_usec = (time_t)us;
|
|---|
| 2057 |
|
|---|
| 2058 | #if defined(__hpux__)
|
|---|
| 2059 | select(1, 0, 0, 0, &tv);
|
|---|
| 2060 | #else
|
|---|
| 2061 | select(1, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv);
|
|---|
| 2062 | #endif
|
|---|
| 2063 | }
|
|---|
| 2064 | /*--------------------------------------------------------------------------*/
|
|---|
| 2065 | /* M R E A D
|
|---|
| 2066 | *
|
|---|
| 2067 | * This function performs the function of a read(II) but will
|
|---|
| 2068 | * call read(II) multiple times in order to get the requested
|
|---|
| 2069 | * number of characters. This can be necessary because
|
|---|
| 2070 | * network connections don't deliver data with the same
|
|---|
| 2071 | * grouping as it is written with. Written by Robert S. Miles, BRL.
|
|---|
| 2072 | */
|
|---|
| 2073 | int
|
|---|
| 2074 | mread(int s, char* bufp, unsigned n)
|
|---|
| 2075 | {
|
|---|
| 2076 | register unsigned count = 0;
|
|---|
| 2077 | register int nread;
|
|---|
| 2078 |
|
|---|
| 2079 | do
|
|---|
| 2080 | {
|
|---|
| 2081 | #if defined(__NTVIS__)
|
|---|
| 2082 | nread = recv(s, bufp, n-count, 0);
|
|---|
| 2083 | #else
|
|---|
| 2084 | nread = read(s, bufp, n-count);
|
|---|
| 2085 | #endif /* __NTVIS__ */
|
|---|
| 2086 | numCalls++;
|
|---|
| 2087 | if(nread < 0) {perror("ttcp_mread"); return(-1); }
|
|---|
| 2088 | if(nread == 0) return((int)count);
|
|---|
| 2089 | count += (unsigned)nread;
|
|---|
| 2090 | bufp += nread;
|
|---|
| 2091 | }while(count < n);
|
|---|
| 2092 | return((int)count);
|
|---|
| 2093 | }
|
|---|
| 2094 |
|
|---|
| 2095 | /*--------------------------------------------------------------------------*/
|
|---|
| 2096 | void
|
|---|
| 2097 | open_log()
|
|---|
| 2098 | {static long sysTicks;
|
|---|
| 2099 | #if defined(UNDER_CE)
|
|---|
| 2100 | SYSTEMTIME SystemTime;
|
|---|
| 2101 | #endif
|
|---|
| 2102 | sprintf(logfile,"%s_%s",logfile_head,trans?"t":"r");
|
|---|
| 2103 |
|
|---|
| 2104 | fprintf(stderr,"open the log file >%s<\n",logfile);
|
|---|
| 2105 | if ((fplog = fopen(logfile,"r")) == NULL)
|
|---|
| 2106 |
|
|---|
| 2107 | {if ((fplog = fopen(logfile,"a+")) == NULL)
|
|---|
| 2108 | {fprintf(stderr,"Failure : creation of the file >%s< \n",logfile );
|
|---|
| 2109 | exit(1);
|
|---|
| 2110 | }
|
|---|
| 2111 | else
|
|---|
| 2112 | {fprintf(fplog," creation date : ");
|
|---|
| 2113 | /* get date */
|
|---|
| 2114 | #if defined(UNDER_CE)
|
|---|
| 2115 | GetLocalTime(&SystemTime);
|
|---|
| 2116 | sprintf(fplog,"%02d-%02d-%02d %02d:%02d\n", SystemTime.wDay, month[SystemTime.wMonth - 1],
|
|---|
| 2117 | SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute);
|
|---|
| 2118 | #else
|
|---|
| 2119 | time(&sysTicks);
|
|---|
| 2120 | tms = localtime(&sysTicks);
|
|---|
| 2121 | fprintf(fplog,"%02d-%02d-%02d %02d:%02d\n",
|
|---|
| 2122 | tms->tm_mday, tms->tm_mon, tms->tm_year,tms->tm_hour, tms->tm_min);
|
|---|
| 2123 | #endif
|
|---|
| 2124 |
|
|---|
| 2125 | /* An other version will produce : Mon Aug 4 16:32:16 1997
|
|---|
| 2126 | * long lDxcomsTicks; char *pDateTime;
|
|---|
| 2127 | * time(&lDxcomsTicks);
|
|---|
| 2128 | * pDateTime = ctime(&lDxcomsTicks); *(pDateTime+24) = '\0';
|
|---|
| 2129 | * fprintf(fplog," ttcp called : %s", pDateTime);
|
|---|
| 2130 | */
|
|---|
| 2131 | fprintf(fplog,"format\n");
|
|---|
| 2132 | fprintf(fplog,",buflen, nbuf(byte), bufalign(byte), bufoffset(byte)");
|
|---|
| 2133 | fprintf(fplog,", port, sockbufsize(byte), UserTime(sec), SysTime(sec)\n");
|
|---|
| 2134 | fprintf(fplog,", CPUusage(%%), Validity, nbytes(byte), realt(sec)");
|
|---|
| 2135 | fprintf(fplog,", rate(MB/sec), I/O call, hours*3600+min*60+sec\n\n");
|
|---|
| 2136 | /* day-month-year, hour:minute\n\n"); */
|
|---|
| 2137 | }
|
|---|
| 2138 | } /* file already exist */
|
|---|
| 2139 | else
|
|---|
| 2140 | {fclose (fplog);
|
|---|
| 2141 | if ((fplog = fopen(logfile,"a+")) == NULL)
|
|---|
| 2142 | {fprintf(stderr,"Failure : access of the file >%s< \n",logfile );
|
|---|
| 2143 | exit(1);
|
|---|
| 2144 | }
|
|---|
| 2145 | }
|
|---|
| 2146 | }
|
|---|
| 2147 | /*--------------------------------------------------------------------------*/
|
|---|
| 2148 | void
|
|---|
| 2149 | close_log()
|
|---|
| 2150 | {
|
|---|
| 2151 | #if defined(UNDER_CE)
|
|---|
| 2152 | SYSTEMTIME SystemTime;
|
|---|
| 2153 |
|
|---|
| 2154 | GetLocalTime(&SystemTime);
|
|---|
| 2155 | fprintf(fplog," %d\n", SystemTime.wHour * 3600 + SystemTime.wMinute * 60 + SystemTime.wSecond);
|
|---|
| 2156 | #else
|
|---|
| 2157 | static long sysTicks;
|
|---|
| 2158 | time(&sysTicks);
|
|---|
| 2159 | tms = localtime(&sysTicks);
|
|---|
| 2160 | fprintf(fplog," %d\n",((tms->tm_hour)*3600 + (tms->tm_min)*60 + tms->tm_sec));
|
|---|
| 2161 | #endif
|
|---|
| 2162 | fclose(fplog);
|
|---|
| 2163 | fflush(fplog);
|
|---|
| 2164 | }
|
|---|
| 2165 | /*--------------------------------------------------------------------------*/
|
|---|
| 2166 | /* routine emulating UNIX function under NT */
|
|---|
| 2167 | #if defined(__NTVIS__)
|
|---|
| 2168 |
|
|---|
| 2169 | /*---------------------------------------------------------------------------*/
|
|---|
| 2170 | static void
|
|---|
| 2171 | error(char *pch)
|
|---|
| 2172 | {
|
|---|
| 2173 | if (!opterr) {
|
|---|
| 2174 | return; // without printing
|
|---|
| 2175 | }
|
|---|
| 2176 | fprintf(stderr, "%s: %s: %c\n",
|
|---|
| 2177 | (NULL != progname) ? progname : "getopt", pch, optopt);
|
|---|
| 2178 | }
|
|---|
| 2179 | /*---------------------------------------------------------------------------*/
|
|---|
| 2180 | int
|
|---|
| 2181 | getopt(int argc, char **argv, char *ostr)
|
|---|
| 2182 | {
|
|---|
| 2183 | static char *place = EMSG; /* option letter processing */
|
|---|
| 2184 | register char *oli; /* option letter list index */
|
|---|
| 2185 |
|
|---|
| 2186 | if (!*place) {
|
|---|
| 2187 | // update scanning pointer
|
|---|
| 2188 | if (optind >= argc || *(place = argv[optind]) != '-' || !*++place) {
|
|---|
| 2189 | place = EMSG;
|
|---|
| 2190 | return -1;
|
|---|
| 2191 | }
|
|---|
| 2192 | // place now points to the first char past the initial '-'
|
|---|
| 2193 | if (place[0] == '-') {
|
|---|
| 2194 | // found "--"
|
|---|
| 2195 | // Was the word just a '--'?
|
|---|
| 2196 | if (place[1] == '\0')
|
|---|
| 2197 | ++optind; // yes, so consume the word
|
|---|
| 2198 | // otherwise, the '--' was the start of a longer word,
|
|---|
| 2199 | // so do not consume it.
|
|---|
| 2200 | place = EMSG;
|
|---|
| 2201 | return -1;
|
|---|
| 2202 | }
|
|---|
| 2203 | }
|
|---|
| 2204 |
|
|---|
| 2205 | /* option letter okay? */
|
|---|
| 2206 | if ((optopt = (int)*place++) == (int)':'
|
|---|
| 2207 | || !(oli = strchr(ostr, optopt))) {
|
|---|
| 2208 | if (!*place) {
|
|---|
| 2209 | ++optind;
|
|---|
| 2210 | }
|
|---|
| 2211 | error("illegal option");
|
|---|
| 2212 | return BADCH;
|
|---|
| 2213 | }
|
|---|
| 2214 | if (*++oli != ':') {
|
|---|
| 2215 | /* don't need argument */
|
|---|
| 2216 | optarg = NULL;
|
|---|
| 2217 | if (!*place)
|
|---|
| 2218 | ++optind;
|
|---|
| 2219 | } else {
|
|---|
| 2220 | /* need an argument */
|
|---|
| 2221 | if (*place) {
|
|---|
| 2222 | optarg = place; /* no white space */
|
|---|
| 2223 | } else if (argc <= ++optind) {
|
|---|
| 2224 | /* no arg */
|
|---|
| 2225 | place = EMSG;
|
|---|
| 2226 | error("option requires an argument");
|
|---|
| 2227 | return BADCH;
|
|---|
| 2228 | } else {
|
|---|
| 2229 | optarg = argv[optind]; /* white space */
|
|---|
| 2230 | }
|
|---|
| 2231 | place = EMSG;
|
|---|
| 2232 | ++optind;
|
|---|
| 2233 | }
|
|---|
| 2234 | return optopt; // return option letter
|
|---|
| 2235 | }
|
|---|
| 2236 |
|
|---|
| 2237 | void
|
|---|
| 2238 | usleep(unsigned int microseconds)
|
|---|
| 2239 | {
|
|---|
| 2240 | Sleep(microseconds/1000);
|
|---|
| 2241 | }
|
|---|
| 2242 | #endif /* __NTVIS__ */
|
|---|
| 2243 | /*--------------------------------------------------------------------------*/
|
|---|
| 2244 | /*--------------------------------------------------------------------------*/
|
|---|
| 2245 | void
|
|---|
| 2246 | do_help()
|
|---|
| 2247 | {
|
|---|
| 2248 | char More_help[] =
|
|---|
| 2249 | " Details about the reply: \n"
|
|---|
| 2250 | " Example: \n"
|
|---|
| 2251 | " ttcp-t: buflen=8192, nbuf=100, align=16384/0, port=5010\n"
|
|---|
| 2252 | " ttcp-t: File-Descriptor 0x4 Opened\n"
|
|---|
| 2253 | " # tcp sender -> <host> #\n"
|
|---|
| 2254 | " ttcp-t: 819200 bytes in 1.152557 real seconds = 694.109 KB/sec +++\n"
|
|---|
| 2255 | " ttcp-t: 100 I/O calls, 11.526 msec(real)/call, 0.213 msec(cpu)/call\n"
|
|---|
| 2256 | " ttcp-t: 0.001914user 0.019388sys 0:01real 1% 9i+58d 190maxrss 1+2pf 177+180csw\n"
|
|---|
| 2257 | " ttcp-t: buffer address 0x28000\n"
|
|---|
| 2258 | " ttcp-t: File-Descriptor fd 0x4 Closed\n"
|
|---|
| 2259 | " ttcp done.\n\n"
|
|---|
| 2260 | "cpu seconds == (sec) elapse ru_utime + elapse ru_stime.\n"
|
|---|
| 2261 | " ru_utime == The total amount of time running in user mode.\n"
|
|---|
| 2262 | " ru_stime == The total amount of time spent in the system.\n"
|
|---|
| 2263 | " executing on behalf of the process.\n"
|
|---|
| 2264 | "real seconds == elapse time calculated by the system timer (date).\n"
|
|---|
| 2265 | "I/O calls == I/O call to the driver.\n"
|
|---|
| 2266 | "msec/call == average elapse time (Real seconds) between each I/O.\n"
|
|---|
| 2267 | "calls/sec == invert of msec/call.\n"
|
|---|
| 2268 | "user == (sec.msec) elaspe ru_utime.\n"
|
|---|
| 2269 | "sys == (sec.msec) elapse ru_stime.\n"
|
|---|
| 2270 | "real == (min:sec) CPU seconds.\n"
|
|---|
| 2271 | "%% == Real seconds / CPU seconds.\n"
|
|---|
| 2272 | "(ru_ixrss)i+(ru_idrss)d\n"
|
|---|
| 2273 | " ru_ixrss == An integral value indicating the amount of memory \n"
|
|---|
| 2274 | " used by the text segment that was also shared among\n"
|
|---|
| 2275 | " other processes. This value is expressed in units of\n"
|
|---|
| 2276 | " kilobytes * seconds-of-execution and is calculated \n"
|
|---|
| 2277 | " by adding the number of shared memory pages in use \n"
|
|---|
| 2278 | " each time the internal system clock ticks, and then\n"
|
|---|
| 2279 | " averaging over one-second intervals.\n"
|
|---|
| 2280 | " ru_idrss == An integral value of the amount of unshared memory \n"
|
|---|
| 2281 | " in the data segment of a process (expressed in \n"
|
|---|
| 2282 | " units of kilobytes * seconds-of-execution).\n";
|
|---|
| 2283 |
|
|---|
| 2284 | char More_help1[] =
|
|---|
| 2285 | " (ru_maxrss/2)maxrss.\n"
|
|---|
| 2286 | " ru_maxrss == The maximum size, in kilobytes, of the used\n"
|
|---|
| 2287 | " resident set size. \n"
|
|---|
| 2288 | " (ru_majflt)+(ru_minflt)pf : Page fault\n"
|
|---|
| 2289 | " ru_majflt == The number of page faults serviced that required\n"
|
|---|
| 2290 | " I/O activity.\n"
|
|---|
| 2291 | " ru_minflt == The number of page faults serviced without any\n"
|
|---|
| 2292 | " I/O activity. In this case, I/O activity is \n"
|
|---|
| 2293 | " avoided by reclaiming a page frame from the list \n"
|
|---|
| 2294 | " of pages awaiting reallocation. \n"
|
|---|
| 2295 | "(ru_nvcsw)+(ru_nivcsw)csw : context switch\n"
|
|---|
| 2296 | " ru_nvcsw == The number of times a context switch resulted \n"
|
|---|
| 2297 | " because a process voluntarily gave up the \n"
|
|---|
| 2298 | " processor before its time slice was completed. \n"
|
|---|
| 2299 | " This usually occurs while the process waits \n"
|
|---|
| 2300 | " for availability of a resource.\n"
|
|---|
| 2301 | " ru_nivcsw == The number of times a context switch resulted \n"
|
|---|
| 2302 | " because a higher priority process ran or because\n"
|
|---|
| 2303 | " the current process exceeded its time slice.\n\n";
|
|---|
| 2304 |
|
|---|
| 2305 | char More_help2[] =
|
|---|
| 2306 | "log file format :\n"
|
|---|
| 2307 | " buflen, nbuf(byte), bufalign(byte), bufoffset(byte)\n"
|
|---|
| 2308 | " port, sockbufsize(byte), UserTime(sec), SysTime(sec), CPUusage(%)\n"
|
|---|
| 2309 | " nbytes(byte), realt(sec), rate(MB/sec), I/O call,\n"
|
|---|
| 2310 | " hours*3600+min*60+sec\n\n";
|
|---|
| 2311 |
|
|---|
| 2312 | fprintf(stderr,More_help);
|
|---|
| 2313 | fprintf(stderr,More_help1);
|
|---|
| 2314 | fprintf(stderr,More_help2);
|
|---|
| 2315 | }
|
|---|
| 2316 | /*---------------------------------------------------------------------------*/
|
|---|
| 2317 | void
|
|---|
| 2318 | do_Usage()
|
|---|
| 2319 | {
|
|---|
| 2320 | char Usage[] =
|
|---|
| 2321 | " Usage: ttcp -t [-options] host [ < in ] ttcp -r [-options > out]\n"
|
|---|
| 2322 | "Example: ttcp -t -s -v -n100 host ttcp -r -s -v -n100\n"
|
|---|
| 2323 | "Common options:\n"
|
|---|
| 2324 | " -V prints version number and date of last modification\n"
|
|---|
| 2325 | " -L create and append all results to a file named ttcp_log\n"
|
|---|
| 2326 | " -h more help\n"
|
|---|
| 2327 | " -l ## length of bufs read from or written to network (default 8192,\n"
|
|---|
| 2328 | " max 65535)\n"
|
|---|
| 2329 | " -u use UDP instead of TCP\n"
|
|---|
| 2330 | " -p ## port number to send to or listen at (default 5010)\n"
|
|---|
| 2331 | #if defined(__linux__)
|
|---|
| 2332 | " -P ## link-layer priority (default 0)\n"
|
|---|
| 2333 | #endif
|
|---|
| 2334 | " -s (ttcp -t) : source a pattern to network\n"
|
|---|
| 2335 | " (ttcp -r) : sink (discard) all data from network\n"
|
|---|
| 2336 | " -A ## align the start of buffers to this modulus (default 16384)\n"
|
|---|
| 2337 | " -O ## start buffers at this offset from the modulus (default 0)\n"
|
|---|
| 2338 | " -v verbose: print more statistics\n"
|
|---|
| 2339 | " -d set SO_DEBUG socket option\n"
|
|---|
| 2340 | " -b ## set socket buffer size (if supported)\n"
|
|---|
| 2341 | " -f X format for rate: b,B = bits, bytes k,K = kilo{bits,bytes};\n"
|
|---|
| 2342 | " m,M = mega{bits,bytes}; g,G = giga{bits,bytes}\n"
|
|---|
| 2343 | " -w ## set timeout value (in milliseconds) to exit if no receive data or tcp connect\n"
|
|---|
| 2344 | "Options specific to (ttcp -t) :\n"
|
|---|
| 2345 | " -n ## number of source bufs written to network (default 2048)\n"
|
|---|
| 2346 | " -x use random data in tcp/udp frames (-I provides seed)\n"
|
|---|
| 2347 | " -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n"
|
|---|
| 2348 | " -H print hash marks to indicate progress, one per buffer\n"
|
|---|
| 2349 | " -I init/seed value for RNG when sending random size bufs (default 1)\n"
|
|---|
| 2350 | " -N ## number of source bufs per burst, i.e between sleeps (default 1)\n"
|
|---|
| 2351 | " -R ## send random size buffers with minimum size specified, max size\n"
|
|---|
| 2352 | " is value of -l option\n"
|
|---|
| 2353 | " -S ## millisecs between bursts (only used for udp, 10ms resolution)\n"
|
|---|
| 2354 | "Options specific to (ttcp -r) :\n"
|
|---|
| 2355 | " -B for -s, only output full blocks as specified by -l (for TAR)\n"
|
|---|
| 2356 | " -T \"touch\": access each byte as it's read\n"
|
|---|
| 2357 | " -i report information on out of order sequence numbers\n"
|
|---|
| 2358 | #if defined(DEBUG)
|
|---|
| 2359 | "Options for debug:\n"
|
|---|
| 2360 | " --nostart do not send UDP start packets\n"
|
|---|
| 2361 | " --noend do not send UDP end packets\n"
|
|---|
| 2362 | " --nodata do not send UDP data packets\n"
|
|---|
| 2363 | " --debug print extra debug outputs\n"
|
|---|
| 2364 | #endif /* DEBUG */
|
|---|
| 2365 | ;
|
|---|
| 2366 |
|
|---|
| 2367 | fprintf(stderr,Usage);
|
|---|
| 2368 | }
|
|---|
| 2369 |
|
|---|
| 2370 | /* Define automatic Emacs variables for consistent code formatting */
|
|---|
| 2371 | /* Local Variables: */
|
|---|
| 2372 | /* c-basic-offset:2 */
|
|---|
| 2373 | /* indent-tabs-mode:nil */
|
|---|
| 2374 | /* End: */
|
|---|