diff options
Diffstat (limited to 'benchmarks')
-rw-r--r-- | benchmarks/netio/Makefile | 6 | ||||
-rw-r--r-- | benchmarks/netio/distinfo | 4 | ||||
-rw-r--r-- | benchmarks/netio/files/patch-netio.c | 3408 |
3 files changed, 3131 insertions, 287 deletions
diff --git a/benchmarks/netio/Makefile b/benchmarks/netio/Makefile index 82ed98d8109c..bacb7b860a80 100644 --- a/benchmarks/netio/Makefile +++ b/benchmarks/netio/Makefile @@ -2,11 +2,11 @@ # $FreeBSD$ PORTNAME= netio -PORTVERSION= 1.26 +PORTVERSION= 1.32 CATEGORIES= benchmarks net ipv6 MASTER_SITES= ${MASTER_SITE_LOCAL} MASTER_SITE_SUBDIR= arved -DISTNAME= netio126 +DISTNAME= netio132 MAINTAINER= arved@FreeBSD.org COMMENT= Network benchmark @@ -15,7 +15,7 @@ WRKSRC= ${WRKDIR} USES= gmake zip PLIST_FILES= bin/netio -CFLAGS+= -DUNIX +CFLAGS+= -DUNIX -DSOCKLEN_T LIBS+= -pthread MAKE_ENV+= OUT=-o diff --git a/benchmarks/netio/distinfo b/benchmarks/netio/distinfo index f2ed91c7614d..14a95aeffdff 100644 --- a/benchmarks/netio/distinfo +++ b/benchmarks/netio/distinfo @@ -1,2 +1,2 @@ -SHA256 (netio126.zip) = 86c0bdee3224477b43c0cb6161ce1a20b2a2b6d59ef37f67864227096d9e8d5c -SIZE (netio126.zip) = 140402 +SHA256 (netio132.zip) = c21550dfac6634558a7a79957eed28c46c62e0543017ef9d5c97c49f3cd41ddd +SIZE (netio132.zip) = 162484 diff --git a/benchmarks/netio/files/patch-netio.c b/benchmarks/netio/files/patch-netio.c index 121b1fedaa92..173b68446847 100644 --- a/benchmarks/netio/files/patch-netio.c +++ b/benchmarks/netio/files/patch-netio.c @@ -1,282 +1,3126 @@ ---- netio.c.orig Tue Aug 30 16:47:18 2005 -+++ netio.c Sat Sep 2 13:46:50 2006 -@@ -782,8 +782,13 @@ - const int sobufsize = 131072;
- int nPort = DEFAULTPORT;
- int nAuxPort = DEFAULTPORT + 1;
-+#ifdef USE_IPV6
-+struct in6_addr addr_server;
-+struct in6_addr addr_local;
-+#else
- struct in_addr addr_server;
- struct in_addr addr_local;
-+#endif
-
- int udpsocket, udpd;
- unsigned long nUDPCount;
-@@ -794,7 +799,11 @@ - char *cBuffer;
- CONTROL ctl;
- long long nData;
-+#ifdef USE_IPV6
-+ struct sockaddr_in6 sa_server, sa_client;
-+#else
- struct sockaddr_in sa_server, sa_client;
-+#endif
- int server, client;
- size_t length;
- struct timeval tv;
-@@ -808,7 +817,11 @@ - return THREADRESULT;
- }
-
-+#ifdef USE_IPV6
-+ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
-+#else
- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
-+#endif
- {
- psock_errno("socket()");
- free(cBuffer);
-@@ -818,10 +831,15 @@ - setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
-
-+#ifdef USE_IPV6
-+ sa_server.sin6_family = AF_INET6;
-+ sa_server.sin6_port = htons(nPort);
-+ sa_server.sin6_addr = addr_local;
-+#else
- sa_server.sin_family = AF_INET;
- sa_server.sin_port = htons(nPort);
- sa_server.sin_addr = addr_local;
--
-+#endif
- if (bind(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
- {
- psock_errno("bind()");
-@@ -958,7 +976,11 @@ - long nTime, nResult;
- long long nData;
- int i;
-+#ifdef USE_IPV6
-+ struct sockaddr_in6 sa_server;
-+#else
- struct sockaddr_in sa_server;
-+#endif
- int server;
- int rc;
- int nByte;
-@@ -969,7 +991,11 @@ - return;
- }
-
-+#ifdef USE_IPV6
-+ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
-+#else
- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
-+#endif
- {
- psock_errno("socket()");
- free(cBuffer);
-@@ -979,9 +1005,16 @@ - setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
-
-+#ifdef USE_IPV6
-+ sa_server.sin6_family = AF_INET6;
-+ sa_server.sin6_port = htons(nPort);
-+ sa_server.sin6_addr = addr_server;
-+
-+#else
- sa_server.sin_family = AF_INET;
- sa_server.sin_port = htons(nPort);
- sa_server.sin_addr = addr_server;
-+#endif
-
- if (connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
- {
-@@ -1121,7 +1154,11 @@ - THREAD UDP_Receiver(void *arg)
- {
- char *cBuffer;
-+#ifdef USE_IPV6
-+ struct sockaddr_in6 sa_server, sa_client;
-+#else
- struct sockaddr_in sa_server, sa_client;
-+#endif
- int rc;
- size_t nBytes;
-
-@@ -1131,7 +1168,11 @@ - return THREADRESULT;
- }
-
-+#ifdef USE_IPV6
-+ if ((udpsocket = socket(PF_INET6, SOCK_DGRAM, 0)) < 0)
-+#else
- if ((udpsocket = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-+#endif
- {
- psock_errno("socket(DGRAM)");
- free(cBuffer);
-@@ -1141,9 +1182,15 @@ - setsockopt(udpsocket, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
- setsockopt(udpsocket, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
-
-+#ifdef USE_IPV6
-+ sa_server.sin6_family = AF_INET6;
-+ sa_server.sin6_port = htons(nAuxPort);
-+ sa_server.sin6_addr = addr_local;
-+#else
- sa_server.sin_family = AF_INET;
- sa_server.sin_port = htons(nAuxPort);
- sa_server.sin_addr = addr_local;
-+#endif
-
- if (bind(udpsocket, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
- {
-@@ -1181,7 +1228,11 @@ - char *cBuffer;
- CONTROL ctl;
- long long nData;
-+#ifdef USE_IPV6
-+ struct sockaddr_in6 sa_server, sa_client;
-+#else
- struct sockaddr_in sa_server, sa_client;
-+#endif
- int server, client;
- struct timeval tv;
- fd_set fds;
-@@ -1194,7 +1245,11 @@ - return THREADRESULT;
- }
-
-+#ifdef USE_IPV6
-+ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
-+#else
- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
-+#endif
- {
- psock_errno("socket(STREAM)");
- free(cBuffer);
-@@ -1204,9 +1259,15 @@ - setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
-
-+#ifdef USE_IPV6
-+ sa_server.sin6_family = AF_INET6;
-+ sa_server.sin6_port = htons(nAuxPort);
-+ sa_server.sin6_addr = addr_local;
-+#else
- sa_server.sin_family = AF_INET;
- sa_server.sin_port = htons(nAuxPort);
- sa_server.sin_addr = addr_local;
-+#endif
-
- if (bind(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
- {
-@@ -1252,7 +1313,11 @@ - printf("UDP connection established ... ");
- fflush(stdout);
-
-+#ifdef USE_IPV6
-+ sa_client.sin6_port = htons(nAuxPort);
-+#else
- sa_client.sin_port = htons(nAuxPort);
-+#endif
-
- for (;;)
- {
-@@ -1345,7 +1410,11 @@ - long nTime, nResult, nCount;
- long long nData;
- int i;
-+#ifdef USE_IPV6
-+ struct sockaddr_in6 sa_server;
-+#else
- struct sockaddr_in sa_server;
-+#endif
- int server;
- int rc, nByte;
-
-@@ -1355,7 +1424,11 @@ - return;
- }
-
-+#ifdef USE_IPV6
-+ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
-+#else
- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
-+#endif
- {
- psock_errno("socket()");
- free(cBuffer);
-@@ -1365,9 +1438,15 @@ - setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
-
-+#ifdef USE_IPV6
-+ sa_server.sin6_family = AF_INET6;
-+ sa_server.sin6_port = htons(nAuxPort);
-+ sa_server.sin6_addr = addr_server;
-+#else
- sa_server.sin_family = AF_INET;
- sa_server.sin_port = htons(nAuxPort);
- sa_server.sin_addr = addr_server;
-+#endif
-
- if (connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
- {
-@@ -1669,17 +1748,29 @@ - return psock_errno("sock_init()"), 1;
-
- if (szLocal == 0)
-+#ifdef USE_IPV6
-+ addr_local = in6addr_any;
-+#else
- addr_local.s_addr = INADDR_ANY;
-+#endif
- else
- {
- if (isdigit(*szLocal))
-+#ifdef USE_IPV6
-+ inet_pton(AF_INET6, szLocal, &addr_local);
-+#else
- addr_local.s_addr = inet_addr(szLocal);
-+#endif
- else
- {
- if ((host = gethostbyname(szLocal)) == NULL)
- return psock_errno("gethostbyname()"), 1;
-
-+#ifdef USE_IPV6
-+ addr_local = * (struct in6_addr *) (host->h_addr);
-+#else
- addr_local = * (struct in_addr *) (host->h_addr);
-+#endif
- }
- }
-
-@@ -1689,13 +1780,21 @@ - usage();
-
- if (isdigit(*argv[optind]))
-+#ifdef USE_IPV6
-+ inet_pton(AF_INET6, argv[optind], &addr_server);
-+#else
- addr_server.s_addr = inet_addr(argv[optind]);
-+#endif
- else
- {
- if ((host = gethostbyname(argv[optind])) == NULL)
- return psock_errno("gethostbyname()"), 1;
-
-+#ifdef USE_IPV6
-+ addr_server = * (struct in6_addr *) (host->h_addr);
-+#else
- addr_server = * (struct in_addr *) (host->h_addr);
-+#endif
- }
- }
- }
+--- netio.c.orig 2015-03-22 18:03:25.739744000 +0100 ++++ netio.c 2015-03-22 18:03:36.459543000 +0100 +@@ -1,1505 +1,1618 @@ +-/* netio.c
+- *
+- * Author: Kai-Uwe Rommel <rommel@ars.de>
+- * Created: Wed Sep 25 1996
+- */
+-
+-static char *rcsid =
+-"$Id: netio.c,v 1.32 2012/11/22 16:47:24 Rommel Exp Rommel $";
+-static char *rcsrev = "$Revision: 1.32 $";
+-
+-/*
+- * $Log: netio.c,v $
+- * Revision 1.32 2012/11/22 16:47:24 Rommel
+- * added binding to client sockets, too
+- *
+- * Revision 1.31 2010/10/14 16:44:38 Rommel
+- * fixed sleep calls
+- *
+- * Revision 1.30 2010/10/14 14:32:41 Rommel
+- * removed NetBIOS code
+- * added server side result printing
+- * fixed packet loss calculation (data type bug)
+- *
+- * Revision 1.29 2010/10/14 11:28:19 Rommel
+- * central printing routine
+- *
+- * Revision 1.28 2009/09/07 14:09:39 Rommel
+- * changed number output from bytes/KB to bytes/KB/MB
+- *
+- * Revision 1.27 2008/02/11 09:00:22 Rommel
+- * re-randomize buffer data for each loop run
+- *
+- * Revision 1.26 2005/08/30 14:45:51 Rommel
+- * minor fixes
+- *
+- * Revision 1.25 2004/05/26 07:23:04 Rommel
+- * some more corrections from Oliver Lau and Frank Schnell
+- *
+- * Revision 1.24 2004/05/17 16:01:03 Rommel
+- * fix for _send/_recv from Thomas Jahns
+- *
+- * Revision 1.23 2003/09/30 09:32:22 Rommel
+- * corrections from Matthias Scheler for error handling
+- * added socket buffer size setting
+- * added htonl/ntohl code (hint from Oliver Lau)
+- * restructured send/recv error/result checking
+- * more verbose server side messages
+- * other minor changes
+- *
+- * Revision 1.22 2003/09/22 14:58:33 Rommel
+- * added server side progress messages
+- *
+- * Revision 1.21 2003/08/28 12:44:11 Rommel
+- * fixed display of non-k-multiple packet sizes
+- *
+- * Revision 1.20 2003/08/27 11:05:48 Rommel
+- * allow block size specifikation in bytes or k bytes
+- *
+- * Revision 1.19 2003/08/17 16:53:45 Rommel
+- * added Unix/Linux pthreads support (required for UDP)
+- *
+- * Revision 1.18 2003/08/17 14:46:17 Rommel
+- * added UDP benchmark
+- * several minor changes (cleanup)
+- * configurable binding address
+- *
+- * Revision 1.17 2003/07/12 17:25:00 Rommel
+- * made block size selectable
+- *
+- * Revision 1.16 2003/02/10 09:06:59 Rommel
+- * fixed sender algorithm
+- *
+- * Revision 1.15 2001/09/17 13:56:40 Rommel
+- * changed to perform bidirectional benchmarks
+- *
+- * Revision 1.14 2001/04/19 12:20:55 Rommel
+- * added fixes for Unix systems
+- *
+- * Revision 1.13 2001/03/26 11:37:41 Rommel
+- * avoid integer overflows during throughput calculation
+- *
+- * Revision 1.12 2000/12/01 15:57:57 Rommel
+- * *** empty log message ***
+- *
+- * Revision 1.11 2000/03/01 12:21:47 rommel
+- * fixed _INTEGRAL_MAX_BITS problem for WIN32
+- *
+- * Revision 1.10 1999/10/28 17:36:57 rommel
+- * fixed OS/2 timer code
+- *
+- * Revision 1.9 1999/10/28 17:04:12 rommel
+- * fixed timer code
+- *
+- * Revision 1.8 1999/10/24 19:08:20 rommel
+- * imported DOS support from G. Vanem <giva@bgnett.no>
+- *
+- *
+- * Revision 1.8 1999/10/12 11:02:00 giva
+- * added Watt-32 with djgpp support. Added debug mode.
+- * G. Vanem <giva@bgnett.no>
+- *
+- * Revision 1.7 1999/06/13 18:42:25 rommel
+- * added Linux port with patches from Detlef Plotzky <plo@bvu.de>
+- *
+- * Revision 1.6 1998/10/12 11:14:58 rommel
+- * change to malloc'ed (and tiled) memory for transfer buffers
+- * (hint from Guenter Kukkukk <kukuk@berlin.snafu.de>)
+- * for increased performance
+- *
+- * Revision 1.5 1998/07/31 14:15:03 rommel
+- * added random buffer data
+- * fixed bugs
+- *
+- * Revision 1.4 1997/09/12 17:35:04 rommel
+- * termination bug fixes
+- *
+- * Revision 1.3 1997/09/12 12:00:15 rommel
+- * added Win32 port
+- * (tested for Windows NT only)
+- *
+- * Revision 1.2 1997/09/12 10:44:22 rommel
+- * added TCP/IP and a command line interface
+- *
+- * Revision 1.1 1996/09/25 08:42:29 rommel
+- * Initial revision
+- *
+- */
+-
+-#ifdef WIN32
+-#define _INTEGRAL_MAX_BITS 64
+-#endif
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <ctype.h>
+-#include <signal.h>
+-#if defined(UNIX) || defined(DJGPP)
+-#include <sys/time.h>
+-#include <unistd.h>
+-#include <errno.h>
+-#else
+-#include <process.h>
+-#include "getopt.h"
+-#endif
+-
+-#define DEFAULTPORT 0x494F /* "IO" */
+-#define DEFAULTNBSRV "NETIOSRV"
+-#define DEFAULTNBCLT "NETIOCLT"
+-#define THREADSTACK 65536
+-
+-/* TCP/IP system specific details */
+-
+-#ifdef OS2
+-
+-#define BSD_SELECT
+-#include <types.h>
+-#include <netinet/in.h>
+-#include <sys/select.h>
+-#include <sys/socket.h>
+-#include <sys/time.h>
+-#include <netdb.h>
+-
+-#ifdef __IBMC__
+-#define newthread(entry) (_beginthread(entry, 0, THREADSTACK, 0) == -1)
+-#else
+-#define newthread(entry) (_beginthread(entry, THREADSTACK, 0) == -1)
+-#endif
+-#define THREAD void
+-#define THREADRESULT
+-
+-#endif /* OS2 */
+-
+-#ifdef WATT32
+-
+-#include <tcp.h> /* sock_init() etc. */
+-#include <netinet/in.h>
+-#include <sys/socket.h>
+-#include <netdb.h>
+-#define soclose close_s
+-#define select select_s
+-#define psock_errno perror
+-
+-#endif /* WATT32 */
+-
+-#ifdef WIN32
+-
+-#include <windows.h>
+-#include <winsock.h>
+-#define soclose closesocket
+-
+-int sock_init(void)
+-{
+- WSADATA wsaData;
+- return WSAStartup(MAKEWORD(1, 1), &wsaData);
+-}
+-
+-void psock_errno(char *text)
+-{
+- int rc = WSAGetLastError();
+- printf("%s: error code %d\n", text, rc);
+-}
+-
+-#ifdef __IBMC__
+-#define newthread(entry) (_beginthread(entry, 0, THREADSTACK, 0) == -1)
+-#else
+-#define newthread(entry) (_beginthread(entry, THREADSTACK, 0) == -1)
+-#endif
+-#define THREAD void
+-#define THREADRESULT
+-
+-#endif /* WIN32 */
+-
+-#ifdef UNIX
+-
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <sys/time.h>
+-#include <time.h>
+-#include <netinet/in.h>
+-#include <netdb.h>
+-
+-#define psock_errno(x) perror(x)
+-#define soclose(x) close(x)
+-
+-int sock_init(void)
+-{
+- return 0;
+-}
+-
+-#include <pthread.h>
+-pthread_t thread;
+-#define newthread(entry) (pthread_create(&thread, 0, entry, 0) != 0)
+-#define THREAD void*
+-#define THREADRESULT ((void*)0)
+-
+-#endif /* UNIX */
+-
+-#ifdef SOCKLEN_T
+-typedef socklen_t socklen_type;
+-#else
+-typedef size_t socklen_type;
+-#endif
+-
+-/* global data */
+-
+-#ifndef max
+-#define max(x, y) ((x) > (y) ? (x) : (y))
+-#endif
+-
+-#ifndef min
+-#define min(x, y) ((x) < (y) ? (x) : (y))
+-#endif
+-
+-#ifndef EINTR
+-#define EINTR 0
+-#endif
+-
+-int nSizes[] = {1024, 2048, 4096, 8192, 16384, 32768};
+-size_t nnSizes = sizeof(nSizes) / sizeof(int);
+-#define NMAXSIZE 65536
+-
+-int tSizes[] = {1024, 2048, 4096, 8192, 16384, 32767};
+-size_t ntSizes = sizeof(tSizes) / sizeof(int);
+-#define TMAXSIZE 65536
+-
+-#define INTERVAL 6
+-
+-/* you may need to adapt this to your platform/compiler */
+-typedef unsigned int uint32;
+-
+-typedef struct
+-{
+- uint32 cmd;
+- uint32 data;
+-}
+-CONTROL;
+-
+-#define CMD_QUIT 0
+-#define CMD_C2S 1
+-#define CMD_S2C 2
+-#define CMD_RES 3
+-
+-#define CTLSIZE sizeof(CONTROL)
+-
+-/* timer code */
+-
+-int bTimeOver;
+-
+-#ifdef OS2
+-
+-#define INCL_DOS
+-#define INCL_NOPM
+-#include <os2.h>
+-
+-typedef QWORD TIMER;
+-
+-void APIENTRY TimerThread(ULONG nSeconds)
+-{
+- HEV hSem;
+- HTIMER hTimer;
+-
+- DosCreateEventSem(0, &hSem, DC_SEM_SHARED, 0);
+-
+- DosAsyncTimer(nSeconds * 1000, (HSEM) hSem, &hTimer);
+- DosWaitEventSem(hSem, SEM_INDEFINITE_WAIT);
+- DosStopTimer(hTimer);
+-
+- DosCloseEventSem(hSem);
+-
+- bTimeOver = 1;
+-
+- DosExit(EXIT_THREAD, 0);
+-}
+-
+-int StartAlarm(long nSeconds)
+-{
+- TID ttid;
+-
+- bTimeOver = 0;
+-
+- if (DosCreateThread(&ttid, TimerThread, nSeconds, 0, THREADSTACK))
+- return printf("Cannot create timer thread.\n"), -1;
+-
+- return 0;
+-}
+-
+-int StartTimer(TIMER *nStart)
+-{
+- if (DosTmrQueryTime(nStart))
+- return printf("Timer error.\n"), -1;
+-
+- return 0;
+-}
+-
+-long StopTimer(TIMER *nStart, int nAccuracy)
+-{
+- TIMER nStop;
+- ULONG nFreq;
+-
+- if (DosTmrQueryTime(&nStop))
+- return printf("Timer error.\n"), -1;
+- if (DosTmrQueryFreq(&nFreq))
+- return printf("Timer error.\n"), -1;
+-
+- nFreq = (nFreq + nAccuracy / 2) / nAccuracy;
+-
+- return (* (long long *) &nStop - * (long long *) nStart) / nFreq;
+-}
+-
+-#endif /* OS2 */
+-
+-#ifdef WIN32
+-
+-typedef LARGE_INTEGER TIMER;
+-
+-#define sleep(x) Sleep((x) * 1000);
+-
+-DWORD CALLBACK TimerThread(void *pArg)
+-{
+- long nSeconds = * (long *) pArg;
+-
+- Sleep(nSeconds * 1000);
+- bTimeOver = 1;
+-
+- return 0;
+-}
+-
+-int StartAlarm(long nSeconds)
+-{
+- static long sSeconds;
+- DWORD ttid;
+-
+- sSeconds = nSeconds;
+-
+- bTimeOver = 0;
+-
+- if (CreateThread(0, THREADSTACK, TimerThread, (void *) &sSeconds, 0, &ttid) == NULL)
+- return printf("Cannot create timer thread.\n"), -1;
+-
+- return 0;
+-}
+-
+-int StartTimer(TIMER *nStart)
+-{
+- if (!QueryPerformanceCounter(nStart))
+- return printf("Timer error.\n"), -1;
+-
+- return 0;
+-}
+-
+-long StopTimer(TIMER *nStart, int nAccuracy)
+-{
+- TIMER nStop, nFreq;
+-
+- if (!QueryPerformanceCounter(&nStop))
+- return printf("Timer error.\n"), -1;
+- if (!QueryPerformanceFrequency(&nFreq))
+- return printf("Timer error.\n"), -1;
+-
+- nFreq.QuadPart = (nFreq.QuadPart + nAccuracy / 2) / nAccuracy;
+-
+- return (nStop.QuadPart - nStart->QuadPart) / nFreq.QuadPart;
+-}
+-
+-#endif /* WIN32 */
+-
+-#if defined(UNIX) || defined(DJGPP)
+-
+-typedef struct timeval TIMER;
+-
+-void on_alarm(int signum)
+-{
+- alarm(0);
+- bTimeOver = 1;
+-}
+-
+-int StartAlarm(long nSeconds)
+-{
+- bTimeOver = 0;
+- signal(SIGALRM, on_alarm);
+- alarm(nSeconds);
+- return 0;
+-}
+-
+-int StartTimer(TIMER *nStart)
+-{
+- struct timezone tz = {0, 0};
+-
+- gettimeofday(nStart, &tz);
+-
+- return 0;
+-}
+-
+-long StopTimer(TIMER *nStart, int nAccuracy)
+-{
+- struct timezone tz = {0, 0};
+- TIMER nStop;
+-
+- gettimeofday(&nStop, &tz);
+-
+- return (nStop.tv_sec - nStart->tv_sec) * nAccuracy
+- + (nStop.tv_usec - nStart->tv_usec) * nAccuracy / 1000000;
+-}
+-
+-#endif /* UNIX || DJGPP */
+-
+-/* initialize data to transfer */
+-
+-void GenerateRandomData(char *cBuffer, size_t nSize)
+-{
+- if (cBuffer != NULL)
+- {
+- size_t i;
+-
+- cBuffer[0] = 0;
+- srand(time(NULL));
+-
+- for (i = 1; i < nSize; i++)
+- cBuffer[i] = (char) rand();
+- }
+-}
+-
+-char *InitBuffer(size_t nSize)
+-{
+- char *cBuffer = malloc(nSize);
+- GenerateRandomData(cBuffer, nSize);
+- return cBuffer;
+-}
+-
+-char *PacketSize(int nSize)
+-{
+- static char szBuffer[64];
+-
+- if ((nSize % 1024) == 0 || (nSize % 1024) == 1023)
+- sprintf(szBuffer, "%2dk", (nSize + 512) / 1024);
+- else
+- sprintf(szBuffer, "%d", nSize);
+-
+- return szBuffer;
+-}
+-
+-/* print results */
+-
+-typedef enum {nf_auto, nf_bytes, nf_kbytes, nf_mbytes, nf_gbytes} numberformat;
+-numberformat nFormat = nf_auto;
+-
+-void print_result(long long nData, long nTime)
+-{
+- numberformat nThisFormat = nFormat;
+- double nResult;
+-
+- if (nThisFormat == nf_auto)
+- {
+- if (nData < 10 * 1024 * INTERVAL)
+- nThisFormat = nf_bytes;
+- else if (nData < 10 * 1024 * 1024 * INTERVAL)
+- nThisFormat = nf_kbytes;
+- else if (nData < (long long) 1024 * 1024 * 1024 * INTERVAL)
+- nThisFormat = nf_mbytes;
+- else
+- nThisFormat = nf_gbytes;
+- }
+-
+- switch(nThisFormat)
+- {
+- case nf_bytes:
+- nResult = (double) nData * 1024 / nTime;
+- printf(" %0.0f Byte/s", nResult);
+- break;
+-
+- case nf_kbytes:
+- nResult = (double) nData / nTime;
+- printf(" %0.2f KByte/s", nResult);
+- break;
+-
+- case nf_mbytes:
+- nResult = (double) nData / nTime / 1024;
+- printf(" %0.2f MByte/s", nResult);
+- break;
+-
+- case nf_gbytes:
+- nResult = (double) nData / nTime / 1024 / 1024;
+- printf(" %0.3f GByte/s", nResult);
+- break;
+- }
+-}
+-
+-/* TCP/IP code */
+-
+-int send_data(int socket, void *buffer, size_t size, int flags)
+-{
+- int rc = send(socket, buffer, size, flags);
+-
+- if (rc < 0)
+- {
+- psock_errno("send()");
+- return -1;
+- }
+-
+- if (rc != size)
+- return 1;
+-
+- return 0;
+-}
+-
+-int recv_data(int socket, void *buffer, size_t size, int flags)
+-{
+- size_t rc = recv(socket, buffer, size, flags);
+-
+- if (rc < 0)
+- {
+- psock_errno("recv()");
+- return -1;
+- }
+-
+- if (rc != size)
+- return 1;
+-
+- return 0;
+-}
+-
+-const int sobufsize = 131072;
+-int nPort = DEFAULTPORT;
+-int nAuxPort = DEFAULTPORT + 1;
+-struct in_addr addr_server;
+-struct in_addr addr_local;
+-
+-int udpsocket, udpd;
+-unsigned long nUDPCount;
+-long long nUDPData;
+-
+-THREAD TCP_Server(void *arg)
+-{
+- char *cBuffer;
+- CONTROL ctl;
+- TIMER nTimer;
+- long nTime;
+- long long nData;
+- struct sockaddr_in sa_server, sa_client;
+- int server, client;
+- socklen_type length;
+- struct timeval tv;
+- fd_set fds;
+- int rc;
+- int nByte;
+-
+- if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL)
+- {
+- perror("malloc()");
+- return THREADRESULT;
+- }
+-
+- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+- {
+- psock_errno("socket()");
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- sa_server.sin_family = AF_INET;
+- sa_server.sin_port = htons(nPort);
+- sa_server.sin_addr = addr_local;
+-
+- if (bind(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
+- {
+- psock_errno("bind()");
+- soclose(server);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- if (listen(server, 2) != 0)
+- {
+- psock_errno("listen()");
+- soclose(server);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- for (;;)
+- {
+- printf("TCP server listening.\n");
+-
+- FD_ZERO(&fds);
+- FD_SET(server, &fds);
+- tv.tv_sec = 3600;
+- tv.tv_usec = 0;
+-
+- if ((rc = select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0)
+- {
+- psock_errno("select()");
+- break;
+- }
+-
+- if (rc == 0 || FD_ISSET(server, &fds) == 0)
+- continue;
+-
+- length = sizeof(sa_client);
+- if ((client = accept(server, (struct sockaddr *) &sa_client, &length)) == -1)
+- continue;
+-
+- setsockopt(client, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(client, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- printf("TCP connection established ... ");
+- fflush(stdout);
+-
+- for (;;)
+- {
+- if (recv_data(client, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- ctl.cmd = ntohl(ctl.cmd);
+- ctl.data = ntohl(ctl.data);
+-
+- if (ctl.cmd == CMD_C2S)
+- {
+- StartTimer(&nTimer);
+-
+- printf("\nReceiving from client, packet size %s ... ", PacketSize(ctl.data));
+- nData = 0;
+-
+- do
+- {
+- for (nByte = 0; nByte < ctl.data; )
+- {
+- rc = recv(client, cBuffer + nByte, ctl.data - nByte, 0);
+-
+- if (rc < 0 && errno != EINTR)
+- {
+- psock_errno("recv()");
+- break;
+- }
+-
+- if (rc > 0)
+- nByte += rc;
+- }
+-
+- nData += ctl.data;
+- }
+- while (cBuffer[0] == 0 && rc > 0);
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) != -1)
+- print_result(nData, nTime);
+- }
+- else if (ctl.cmd == CMD_S2C)
+- {
+- if (StartAlarm(INTERVAL) == 0)
+- {
+- StartTimer(&nTimer);
+-
+- printf("\nSending to client, packet size %s ... ", PacketSize(ctl.data));
+- cBuffer[0] = 0;
+- nData = 0;
+-
+- while (!bTimeOver)
+- {
+- //GenerateRandomData(cBuffer, ctl.data);
+-
+- for (nByte = 0; nByte < ctl.data; )
+- {
+- rc = send(client, cBuffer + nByte, ctl.data - nByte, 0);
+-
+- if (rc < 0 && errno != EINTR)
+- {
+- psock_errno("send()");
+- break;
+- }
+-
+- if (rc > 0)
+- nByte += rc;
+- }
+-
+- nData += ctl.data;
+- }
+-
+- cBuffer[0] = 1;
+-
+- if (send_data(client, cBuffer, ctl.data, 0))
+- break;
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) != -1)
+- print_result(nData, nTime);
+- }
+- }
+- else /* quit */
+- break;
+- }
+-
+- printf("\nDone.\n");
+-
+- soclose(client);
+-
+- if (rc < 0)
+- break;
+- }
+-
+- soclose(server);
+- free(cBuffer);
+-
+- return THREADRESULT;
+-}
+-
+-void TCP_Bench(void *arg)
+-{
+- char *cBuffer;
+- CONTROL ctl;
+- TIMER nTimer;
+- long nTime;
+- long long nData;
+- int i;
+- struct sockaddr_in sa_server, sa_client;
+- int server;
+- int rc;
+- int nByte;
+-
+- if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL)
+- {
+- perror("malloc()");
+- return;
+- }
+-
+- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+- {
+- psock_errno("socket()");
+- free(cBuffer);
+- return;
+- }
+-
+- setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- sa_client.sin_family = AF_INET;
+- sa_client.sin_port = htons(0);
+- sa_client.sin_addr = addr_local;
+-
+- if (bind(server, (struct sockaddr *) &sa_client, sizeof(sa_client)) < 0)
+- {
+- psock_errno("bind()");
+- soclose(server);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- sa_server.sin_family = AF_INET;
+- sa_server.sin_port = htons(nPort);
+- sa_server.sin_addr = addr_server;
+-
+- if (connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
+- {
+- psock_errno("connect()");
+- soclose(server);
+- free(cBuffer);
+- return;
+- }
+-
+- printf("\nTCP connection established.\n");
+-
+- for (i = 0; i < ntSizes; i++)
+- {
+- printf("Packet size %s bytes: ", PacketSize(tSizes[i]));
+- fflush(stdout);
+-
+- /* tell the server we will send it data now */
+-
+- ctl.cmd = htonl(CMD_C2S);
+- ctl.data = htonl(tSizes[i]);
+-
+- if (send_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- /* 1 - Tx test */
+-
+- if (StartAlarm(INTERVAL) == 0)
+- {
+- StartTimer(&nTimer);
+- nData = 0;
+- cBuffer[0] = 0;
+-
+- while (!bTimeOver)
+- {
+- //GenerateRandomData(cBuffer, tSizes[i]);
+-
+- for (nByte = 0; nByte < tSizes[i]; )
+- {
+- rc = send(server, cBuffer + nByte, tSizes[i] - nByte, 0);
+-
+- if (rc < 0 && errno != EINTR)
+- {
+- psock_errno("send()");
+- break;
+- }
+-
+- if (rc > 0)
+- nByte += rc;
+- }
+-
+- nData += tSizes[i];
+- }
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) == -1)
+- printf(" (failed)");
+- else
+- print_result(nData, nTime);
+-
+- printf(" Tx, ");
+- fflush(stdout);
+-
+- cBuffer[0] = 1;
+-
+- if (send_data(server, cBuffer, tSizes[i], 0))
+- break;
+- }
+-
+- /* tell the server we expect him to send us data now */
+-
+- ctl.cmd = htonl(CMD_S2C);
+- ctl.data = htonl(tSizes[i]);
+-
+- if (send_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- /* 2 - Rx test */
+-
+- StartTimer(&nTimer);
+- nData = 0;
+-
+- do
+- {
+- for (nByte = 0; nByte < tSizes[i]; )
+- {
+- rc = recv(server, cBuffer + nByte, tSizes[i] - nByte, 0);
+-
+- if (rc < 0 && errno != EINTR)
+- {
+- psock_errno("recv()");
+- break;
+- }
+-
+- if (rc > 0)
+- nByte += rc;
+- }
+-
+- nData += tSizes[i];
+- }
+- while (cBuffer[0] == 0 && rc > 0);
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) == -1)
+- printf(" (failed)");
+- else
+- print_result(nData, nTime);
+-
+- printf(" Rx.\n");
+- }
+-
+- ctl.cmd = htonl(CMD_QUIT);
+- ctl.data = 0;
+-
+- send_data(server, (void *) &ctl, CTLSIZE, 0);
+-
+- printf("Done.\n");
+-
+- soclose(server);
+- free(cBuffer);
+-}
+-
+-THREAD UDP_Receiver(void *arg)
+-{
+- char *cBuffer;
+- struct sockaddr_in sa_server, sa_client;
+- int rc;
+- socklen_type nBytes;
+-
+- if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL)
+- {
+- perror("malloc()");
+- return THREADRESULT;
+- }
+-
+- if ((udpsocket = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+- {
+- psock_errno("socket(DGRAM)");
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- setsockopt(udpsocket, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(udpsocket, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- sa_server.sin_family = AF_INET;
+- sa_server.sin_port = htons(nAuxPort);
+- sa_server.sin_addr = addr_local;
+-
+- if (bind(udpsocket, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
+- {
+- psock_errno("bind(DGRAM)");
+- soclose(udpsocket);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- udpd = 1;
+-
+- for (;;)
+- {
+- nBytes = sizeof(sa_client);
+- rc = recvfrom(udpsocket, cBuffer, TMAXSIZE, 0, (struct sockaddr *) &sa_client, &nBytes);
+-
+- if (rc < 0 && errno != EINTR)
+- psock_errno("recvfrom()");
+-
+- if (rc > 0)
+- {
+- nUDPCount++;
+- nUDPData += rc;
+- }
+- }
+-
+- soclose(udpsocket);
+- free(cBuffer);
+-
+- return THREADRESULT;
+-}
+-
+-THREAD UDP_Server(void *arg)
+-{
+- char *cBuffer;
+- CONTROL ctl;
+- TIMER nTimer;
+- long nTime;
+- long long nData;
+- struct sockaddr_in sa_server, sa_client;
+- int server, client;
+- struct timeval tv;
+- fd_set fds;
+- int rc, nByte;
+- socklen_type nLength;
+-
+- if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL)
+- {
+- perror("malloc()");
+- return THREADRESULT;
+- }
+-
+- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+- {
+- psock_errno("socket(STREAM)");
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- sa_server.sin_family = AF_INET;
+- sa_server.sin_port = htons(nAuxPort);
+- sa_server.sin_addr = addr_local;
+-
+- if (bind(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
+- {
+- psock_errno("bind(STREAM)");
+- soclose(server);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- if (listen(server, 2) != 0)
+- {
+- psock_errno("listen()");
+- soclose(server);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- for (;;)
+- {
+- printf("UDP server listening.\n");
+-
+- FD_ZERO(&fds);
+- FD_SET(server, &fds);
+- tv.tv_sec = 3600;
+- tv.tv_usec = 0;
+-
+- if ((rc = select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0)
+- {
+- psock_errno("select()");
+- break;
+- }
+-
+- if (rc == 0 || FD_ISSET(server, &fds) == 0)
+- continue;
+-
+- nLength = sizeof(sa_client);
+- if ((client = accept(server, (struct sockaddr *) &sa_client, &nLength)) == -1)
+- continue;
+-
+- setsockopt(client, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(client, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- printf("UDP connection established ... ");
+- fflush(stdout);
+-
+- sa_client.sin_port = htons(nAuxPort);
+-
+- for (;;)
+- {
+- if (recv_data(client, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- ctl.cmd = ntohl(ctl.cmd);
+- ctl.data = ntohl(ctl.data);
+-
+- if (ctl.cmd == CMD_C2S)
+- {
+- StartTimer(&nTimer);
+- nUDPCount = 0;
+- nUDPData = 0;
+-
+- printf("\nReceiving from client, packet size %s ... ", PacketSize(ctl.data));
+-
+- ctl.cmd = htonl(ctl.cmd);
+- ctl.data = htonl(ctl.data);
+-
+- if (send_data(client, (void *) &ctl, CTLSIZE, 0))
+- break;
+- }
+- else if (ctl.cmd == CMD_RES)
+- {
+- ctl.cmd = htonl(ctl.cmd);
+- ctl.data = htonl(nUDPCount);
+-
+- if (send_data(client, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) != -1)
+- print_result(nUDPData, nTime);
+- }
+- else if (ctl.cmd == CMD_S2C)
+- {
+- if (StartAlarm(INTERVAL) == 0)
+- {
+- StartTimer(&nTimer);
+- nData = 0;
+-
+- printf("\nSending to client, packet size %s ... ", PacketSize(ctl.data));
+- cBuffer[0] = 0;
+- nLength = ctl.data;
+-
+- ctl.cmd = htonl(CMD_RES);
+- ctl.data = 0;
+-
+- while (!bTimeOver)
+- {
+- //GenerateRandomData(cBuffer, nLength);
+-
+- for (nByte = 0; nByte < nLength; )
+- {
+- do
+- {
+- rc = sendto(udpsocket, cBuffer + nByte, nLength - nByte, 0,
+- (struct sockaddr *) &sa_client, sizeof(sa_client));
+- }
+-#ifdef ENOBUFS
+- while (rc < 0 && errno == ENOBUFS);
+-#else
+- while (0);
+-#endif
+-
+- if (rc < 0 && errno != EINTR)
+- {
+- psock_errno("sendto()");
+- break;
+- }
+-
+- if (rc > 0)
+- nByte += rc;
+- }
+-
+- ctl.data++;
+- nData += nLength;
+- }
+-
+- ctl.data = htonl(ctl.data);
+-
+- if (send_data(client, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) != -1)
+- print_result(nData, nTime);
+- }
+- }
+- else /* quit */
+- break;
+- }
+-
+- printf("\nDone.\n");
+-
+- soclose(client);
+-
+- if (rc < 0)
+- break;
+- }
+-
+- soclose(server);
+- free(cBuffer);
+-
+- return THREADRESULT;
+-}
+-
+-void UDP_Bench(void *arg)
+-{
+- char *cBuffer;
+- CONTROL ctl;
+- TIMER nTimer;
+- long nTime, nCount;
+- long nResult;
+- long long nData;
+- int i;
+- struct sockaddr_in sa_server, sa_client;
+- int server;
+- int rc, nByte;
+-
+- if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL)
+- {
+- perror("malloc()");
+- return;
+- }
+-
+- if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+- {
+- psock_errno("socket()");
+- free(cBuffer);
+- return;
+- }
+-
+- setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
+- setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
+-
+- sa_client.sin_family = AF_INET;
+- sa_client.sin_port = htons(0);
+- sa_client.sin_addr = addr_local;
+-
+- if (bind(server, (struct sockaddr *) &sa_client, sizeof(sa_client)) < 0)
+- {
+- psock_errno("bind(STREAM)");
+- soclose(server);
+- free(cBuffer);
+- return THREADRESULT;
+- }
+-
+- sa_server.sin_family = AF_INET;
+- sa_server.sin_port = htons(nAuxPort);
+- sa_server.sin_addr = addr_server;
+-
+- if (connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0)
+- {
+- psock_errno("connect()");
+- soclose(server);
+- free(cBuffer);
+- return;
+- }
+-
+- printf("\nUDP connection established.\n");
+-
+- for (i = 0; i < ntSizes; i++)
+- {
+- printf("Packet size %s bytes: ", PacketSize(tSizes[i]));
+- fflush(stdout);
+-
+- /* tell the server we will send it data now */
+-
+- ctl.cmd = htonl(CMD_C2S);
+- ctl.data = htonl(tSizes[i]);
+-
+- if (send_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- if (recv_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- /* 1 - Tx test */
+-
+- if (StartAlarm(INTERVAL) == 0)
+- {
+- StartTimer(&nTimer);
+- nData = 0;
+- nCount = 0;
+- cBuffer[0] = 0;
+-
+- while (!bTimeOver)
+- {
+- //GenerateRandomData(cBuffer, tSizes[i]);
+-
+- for (nByte = 0; nByte < tSizes[i]; )
+- {
+- rc = sendto(udpsocket, cBuffer + nByte, tSizes[i] - nByte, 0,
+- (struct sockaddr *) &sa_server, sizeof(sa_server));
+-
+- if (rc < 0)
+- {
+- if (errno != EINTR)
+- {
+- psock_errno("sendto()");
+- break;
+- }
+- }
+- else
+- nByte += rc;
+- }
+-
+- nData += tSizes[i];
+- nCount++;
+- }
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) == -1)
+- printf(" (failed)");
+-
+- ctl.cmd = htonl(CMD_RES);
+-
+- if (send_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- if (recv_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- ctl.data = ntohl(ctl.data);
+- nData = (long long) tSizes[i] * ctl.data;
+-
+- print_result(nData, nTime);
+- nResult = (nCount - ctl.data) * 100 / nCount;
+- printf(" (%ld%%) Tx, ", nResult);
+- fflush(stdout);
+- }
+-
+- /* tell the server we expect him to send us data now */
+-
+- ctl.cmd = htonl(CMD_S2C);
+- ctl.data = htonl(tSizes[i]);
+-
+- if (send_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- /* 2 - Rx test */
+-
+- StartTimer(&nTimer);
+- nUDPCount = 0;
+- nUDPData = 0;
+-
+- if (recv_data(server, (void *) &ctl, CTLSIZE, 0))
+- break;
+-
+- if ((nTime = StopTimer(&nTimer, 1024)) == -1)
+- printf(" (failed)");
+-
+- ctl.data = ntohl(ctl.data);
+-
+- print_result(nUDPData, nTime);
+- nResult = (ctl.data - nUDPCount) * 100 / ctl.data;
+- printf(" (%ld%%) Rx.\n", nResult);
+- }
+-
+- ctl.cmd = htonl(CMD_QUIT);
+- ctl.data = 0;
+-
+- send_data(server, (void *) &ctl, CTLSIZE, 0);
+-
+- printf("Done.\n");
+-
+- soclose(server);
+- free(cBuffer);
+-}
+-
+-/* main / user interface */
+-
+-int bSRV, bTCP, bUDP;
+-
+-void handler(int sig)
+-{
+- _exit(0);
+-}
+-
+-void usage(void)
+-{
+- printf(
+- "\nUsage: netio [options] [<server>]\n"
+- "\n -s run server side of benchmark (otherwise run client)"
+- "\n -b <size>[k] use this block size (otherwise run with 1,2,4,8,16 and 32k)"
+- "\n -B -K -M -G force number formatting to Bytes, K, M or G Bytes\n"
+-
+- "\n -t use TCP protocol for benchmark"
+- "\n -u use UDP protocol for benchmark"
+- "\n -h <addr/name> bind TCP and UDP sockets to this local host address/name"
+- "\n defaults to all (server) or unspecified (client)"
+- "\n -p <port> bind TCP and UDP servers to this port (default is %d)\n"
+-
+- "\n <server> If the client side of the benchmark is running,"
+- "\n a server name or address is required.\n"
+-
+- "\nThe server side can run either TCP (-t) or UDP (-u) protocol or both"
+- "\n(default, if neither -t or -u is specified). The client runs one of"
+- "\nthese protocols only (must specify -t or -u).\n"
+- "\n", nPort);
+- exit(1);
+-}
+-
+-int main(int argc, char **argv)
+-{
+- char szVersion[32], *szName = 0, *szLocal = 0, *szEnd;
+- int option;
+- struct hostent *host;
+- long nSize;
+-
+- strcpy(szVersion, rcsrev + sizeof("$Revision: ") - 1);
+- *strchr(szVersion, ' ') = 0;
+-
+- printf("\nNETIO - Network Throughput Benchmark, Version %s"
+- "\n(C) 1997-2012 Kai Uwe Rommel\n", szVersion);
+-
+- if (argc == 1)
+- usage();
+-
+- /* check arguments */
+-
+- while ((option = getopt(argc, argv, "?stup:h:b:dBKMG")) != -1)
+- switch (option)
+- {
+- case 's':
+- bSRV = 1;
+- break;
+- case 't':
+- bTCP = 1;
+- break;
+- case 'u':
+- bUDP = 1;
+- break;
+- case 'p':
+- nPort = atoi(optarg);
+- nAuxPort = nPort + 1;
+- break;
+- case 'h':
+- szLocal = optarg;
+- break;
+- case 'b':
+- nSize = strtol(optarg, &szEnd, 10);
+- if (*szEnd == 'k')
+- nSize *= 1024;
+- nSizes[0] = min(max(nSize, 1), NMAXSIZE);
+- tSizes[0] = min(max(nSize, 1), TMAXSIZE);
+- nnSizes = ntSizes = 1;
+- break;
+-#ifdef WATT32
+- case 'd':
+- dbug_init();
+- break;
+-#endif
+- case 'B':
+- nFormat = nf_bytes;
+- break;
+- case 'K':
+- nFormat = nf_kbytes;
+- break;
+- case 'M':
+- nFormat = nf_mbytes;
+- break;
+- case 'G':
+- nFormat = nf_gbytes;
+- break;
+- default:
+- usage();
+- break;
+- }
+-
+- if (bSRV == 1 && bTCP == 0 && bUDP == 0)
+- bTCP = bUDP = 1;
+-
+- /* initialize TCP/IP */
+-
+- if (bTCP || bUDP)
+- {
+- if (sock_init())
+- return psock_errno("sock_init()"), 1;
+-
+- if (szLocal == 0)
+- addr_local.s_addr = INADDR_ANY;
+- else
+- {
+- if (isdigit(*szLocal))
+- addr_local.s_addr = inet_addr(szLocal);
+- else
+- {
+- if ((host = gethostbyname(szLocal)) == NULL)
+- return psock_errno("gethostbyname()"), 1;
+-
+- addr_local = * (struct in_addr *) (host->h_addr);
+- }
+- }
+-
+- if (!bSRV)
+- {
+- if (optind == argc)
+- usage();
+-
+- if (isdigit(*argv[optind]))
+- addr_server.s_addr = inet_addr(argv[optind]);
+- else
+- {
+- if ((host = gethostbyname(argv[optind])) == NULL)
+- return psock_errno("gethostbyname()"), 1;
+-
+- addr_server = * (struct in_addr *) (host->h_addr);
+- }
+- }
+- }
+-
+- /* do work */
+-
+- signal(SIGINT, handler);
+-
+- if (bSRV)
+- {
+- printf("\n");
+-
+- if (bTCP)
+- {
+- if (newthread(TCP_Server))
+- return printf("Cannot create additional thread.\n"), 2;
+- }
+- if (bUDP)
+- {
+- if (newthread(UDP_Receiver))
+- return printf("Cannot create additional thread.\n"), 2;
+- if (newthread(UDP_Server))
+- return printf("Cannot create additional thread.\n"), 2;
+- }
+-
+- for (;;) sleep(86400);
+- }
+- else
+- {
+- if (bTCP + bUDP > 1) /* exactly one only */
+- usage();
+-
+- if (bTCP)
+- TCP_Bench(0);
+- else if (bUDP)
+- {
+- if (newthread(UDP_Receiver))
+- return printf("Cannot create additional thread.\n"), 2;
+- while (udpd == 0) sleep(1);
+- UDP_Bench(0);
+- }
+- }
+-
+- /* terminate */
+-
+- printf("\n");
+-
+- return 0;
+-}
+-
+-/* end of netio.c */
++/* netio.c ++ * ++ * Author: Kai-Uwe Rommel <rommel@ars.de> ++ * Created: Wed Sep 25 1996 ++ */ ++ ++static char *rcsid = ++"$Id: netio.c,v 1.32 2012/11/22 16:47:24 Rommel Exp Rommel $"; ++static char *rcsrev = "$Revision: 1.32 $"; ++ ++/* ++ * $Log: netio.c,v $ ++ * Revision 1.32 2012/11/22 16:47:24 Rommel ++ * added binding to client sockets, too ++ * ++ * Revision 1.31 2010/10/14 16:44:38 Rommel ++ * fixed sleep calls ++ * ++ * Revision 1.30 2010/10/14 14:32:41 Rommel ++ * removed NetBIOS code ++ * added server side result printing ++ * fixed packet loss calculation (data type bug) ++ * ++ * Revision 1.29 2010/10/14 11:28:19 Rommel ++ * central printing routine ++ * ++ * Revision 1.28 2009/09/07 14:09:39 Rommel ++ * changed number output from bytes/KB to bytes/KB/MB ++ * ++ * Revision 1.27 2008/02/11 09:00:22 Rommel ++ * re-randomize buffer data for each loop run ++ * ++ * Revision 1.26 2005/08/30 14:45:51 Rommel ++ * minor fixes ++ * ++ * Revision 1.25 2004/05/26 07:23:04 Rommel ++ * some more corrections from Oliver Lau and Frank Schnell ++ * ++ * Revision 1.24 2004/05/17 16:01:03 Rommel ++ * fix for _send/_recv from Thomas Jahns ++ * ++ * Revision 1.23 2003/09/30 09:32:22 Rommel ++ * corrections from Matthias Scheler for error handling ++ * added socket buffer size setting ++ * added htonl/ntohl code (hint from Oliver Lau) ++ * restructured send/recv error/result checking ++ * more verbose server side messages ++ * other minor changes ++ * ++ * Revision 1.22 2003/09/22 14:58:33 Rommel ++ * added server side progress messages ++ * ++ * Revision 1.21 2003/08/28 12:44:11 Rommel ++ * fixed display of non-k-multiple packet sizes ++ * ++ * Revision 1.20 2003/08/27 11:05:48 Rommel ++ * allow block size specifikation in bytes or k bytes ++ * ++ * Revision 1.19 2003/08/17 16:53:45 Rommel ++ * added Unix/Linux pthreads support (required for UDP) ++ * ++ * Revision 1.18 2003/08/17 14:46:17 Rommel ++ * added UDP benchmark ++ * several minor changes (cleanup) ++ * configurable binding address ++ * ++ * Revision 1.17 2003/07/12 17:25:00 Rommel ++ * made block size selectable ++ * ++ * Revision 1.16 2003/02/10 09:06:59 Rommel ++ * fixed sender algorithm ++ * ++ * Revision 1.15 2001/09/17 13:56:40 Rommel ++ * changed to perform bidirectional benchmarks ++ * ++ * Revision 1.14 2001/04/19 12:20:55 Rommel ++ * added fixes for Unix systems ++ * ++ * Revision 1.13 2001/03/26 11:37:41 Rommel ++ * avoid integer overflows during throughput calculation ++ * ++ * Revision 1.12 2000/12/01 15:57:57 Rommel ++ * *** empty log message *** ++ * ++ * Revision 1.11 2000/03/01 12:21:47 rommel ++ * fixed _INTEGRAL_MAX_BITS problem for WIN32 ++ * ++ * Revision 1.10 1999/10/28 17:36:57 rommel ++ * fixed OS/2 timer code ++ * ++ * Revision 1.9 1999/10/28 17:04:12 rommel ++ * fixed timer code ++ * ++ * Revision 1.8 1999/10/24 19:08:20 rommel ++ * imported DOS support from G. Vanem <giva@bgnett.no> ++ * ++ * ++ * Revision 1.8 1999/10/12 11:02:00 giva ++ * added Watt-32 with djgpp support. Added debug mode. ++ * G. Vanem <giva@bgnett.no> ++ * ++ * Revision 1.7 1999/06/13 18:42:25 rommel ++ * added Linux port with patches from Detlef Plotzky <plo@bvu.de> ++ * ++ * Revision 1.6 1998/10/12 11:14:58 rommel ++ * change to malloc'ed (and tiled) memory for transfer buffers ++ * (hint from Guenter Kukkukk <kukuk@berlin.snafu.de>) ++ * for increased performance ++ * ++ * Revision 1.5 1998/07/31 14:15:03 rommel ++ * added random buffer data ++ * fixed bugs ++ * ++ * Revision 1.4 1997/09/12 17:35:04 rommel ++ * termination bug fixes ++ * ++ * Revision 1.3 1997/09/12 12:00:15 rommel ++ * added Win32 port ++ * (tested for Windows NT only) ++ * ++ * Revision 1.2 1997/09/12 10:44:22 rommel ++ * added TCP/IP and a command line interface ++ * ++ * Revision 1.1 1996/09/25 08:42:29 rommel ++ * Initial revision ++ * ++ */ ++ ++#ifdef WIN32 ++#define _INTEGRAL_MAX_BITS 64 ++#endif ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <ctype.h> ++#include <signal.h> ++#if defined(UNIX) || defined(DJGPP) ++#include <arpa/inet.h> ++#include <sys/time.h> ++#include <unistd.h> ++#include <errno.h> ++#else ++#include <process.h> ++#include "getopt.h" ++#endif ++ ++#define DEFAULTPORT 0x494F /* "IO" */ ++#define DEFAULTNBSRV "NETIOSRV" ++#define DEFAULTNBCLT "NETIOCLT" ++#define THREADSTACK 65536 ++ ++/* TCP/IP system specific details */ ++ ++#ifdef OS2 ++ ++#define BSD_SELECT ++#include <types.h> ++#include <netinet/in.h> ++#include <sys/select.h> ++#include <sys/socket.h> ++#include <sys/time.h> ++#include <netdb.h> ++ ++#ifdef __IBMC__ ++#define newthread(entry) (_beginthread(entry, 0, THREADSTACK, 0) == -1) ++#else ++#define newthread(entry) (_beginthread(entry, THREADSTACK, 0) == -1) ++#endif ++#define THREAD void ++#define THREADRESULT ++ ++#endif /* OS2 */ ++ ++#ifdef WATT32 ++ ++#include <tcp.h> /* sock_init() etc. */ ++#include <netinet/in.h> ++#include <sys/socket.h> ++#include <netdb.h> ++#define soclose close_s ++#define select select_s ++#define psock_errno perror ++ ++#endif /* WATT32 */ ++ ++#ifdef WIN32 ++ ++#include <windows.h> ++#include <winsock.h> ++#define soclose closesocket ++ ++int sock_init(void) ++{ ++ WSADATA wsaData; ++ return WSAStartup(MAKEWORD(1, 1), &wsaData); ++} ++ ++void psock_errno(char *text) ++{ ++ int rc = WSAGetLastError(); ++ printf("%s: error code %d\n", text, rc); ++} ++ ++#ifdef __IBMC__ ++#define newthread(entry) (_beginthread(entry, 0, THREADSTACK, 0) == -1) ++#else ++#define newthread(entry) (_beginthread(entry, THREADSTACK, 0) == -1) ++#endif ++#define THREAD void ++#define THREADRESULT ++ ++#endif /* WIN32 */ ++ ++#ifdef UNIX ++ ++#include <sys/types.h> ++#include <sys/socket.h> ++#include <sys/time.h> ++#include <time.h> ++#include <netinet/in.h> ++#include <netdb.h> ++ ++#define psock_errno(x) perror(x) ++#define soclose(x) close(x) ++ ++int sock_init(void) ++{ ++ return 0; ++} ++ ++#include <pthread.h> ++pthread_t thread; ++#define newthread(entry) (pthread_create(&thread, 0, entry, 0) != 0) ++#define THREAD void* ++#define THREADRESULT ((void*)0) ++ ++#endif /* UNIX */ ++ ++#ifdef SOCKLEN_T ++typedef socklen_t socklen_type; ++#else ++typedef size_t socklen_type; ++#endif ++ ++/* global data */ ++ ++#ifndef max ++#define max(x, y) ((x) > (y) ? (x) : (y)) ++#endif ++ ++#ifndef min ++#define min(x, y) ((x) < (y) ? (x) : (y)) ++#endif ++ ++#ifndef EINTR ++#define EINTR 0 ++#endif ++ ++int nSizes[] = {1024, 2048, 4096, 8192, 16384, 32768}; ++size_t nnSizes = sizeof(nSizes) / sizeof(int); ++#define NMAXSIZE 65536 ++ ++int tSizes[] = {1024, 2048, 4096, 8192, 16384, 32767}; ++size_t ntSizes = sizeof(tSizes) / sizeof(int); ++#define TMAXSIZE 65536 ++ ++#define INTERVAL 6 ++ ++/* you may need to adapt this to your platform/compiler */ ++typedef unsigned int uint32; ++ ++typedef struct ++{ ++ uint32 cmd; ++ uint32 data; ++} ++CONTROL; ++ ++#define CMD_QUIT 0 ++#define CMD_C2S 1 ++#define CMD_S2C 2 ++#define CMD_RES 3 ++ ++#define CTLSIZE sizeof(CONTROL) ++ ++/* timer code */ ++ ++int bTimeOver; ++ ++#ifdef OS2 ++ ++#define INCL_DOS ++#define INCL_NOPM ++#include <os2.h> ++ ++typedef QWORD TIMER; ++ ++void APIENTRY TimerThread(ULONG nSeconds) ++{ ++ HEV hSem; ++ HTIMER hTimer; ++ ++ DosCreateEventSem(0, &hSem, DC_SEM_SHARED, 0); ++ ++ DosAsyncTimer(nSeconds * 1000, (HSEM) hSem, &hTimer); ++ DosWaitEventSem(hSem, SEM_INDEFINITE_WAIT); ++ DosStopTimer(hTimer); ++ ++ DosCloseEventSem(hSem); ++ ++ bTimeOver = 1; ++ ++ DosExit(EXIT_THREAD, 0); ++} ++ ++int StartAlarm(long nSeconds) ++{ ++ TID ttid; ++ ++ bTimeOver = 0; ++ ++ if (DosCreateThread(&ttid, TimerThread, nSeconds, 0, THREADSTACK)) ++ return printf("Cannot create timer thread.\n"), -1; ++ ++ return 0; ++} ++ ++int StartTimer(TIMER *nStart) ++{ ++ if (DosTmrQueryTime(nStart)) ++ return printf("Timer error.\n"), -1; ++ ++ return 0; ++} ++ ++long StopTimer(TIMER *nStart, int nAccuracy) ++{ ++ TIMER nStop; ++ ULONG nFreq; ++ ++ if (DosTmrQueryTime(&nStop)) ++ return printf("Timer error.\n"), -1; ++ if (DosTmrQueryFreq(&nFreq)) ++ return printf("Timer error.\n"), -1; ++ ++ nFreq = (nFreq + nAccuracy / 2) / nAccuracy; ++ ++ return (* (long long *) &nStop - * (long long *) nStart) / nFreq; ++} ++ ++#endif /* OS2 */ ++ ++#ifdef WIN32 ++ ++typedef LARGE_INTEGER TIMER; ++ ++#define sleep(x) Sleep((x) * 1000); ++ ++DWORD CALLBACK TimerThread(void *pArg) ++{ ++ long nSeconds = * (long *) pArg; ++ ++ Sleep(nSeconds * 1000); ++ bTimeOver = 1; ++ ++ return 0; ++} ++ ++int StartAlarm(long nSeconds) ++{ ++ static long sSeconds; ++ DWORD ttid; ++ ++ sSeconds = nSeconds; ++ ++ bTimeOver = 0; ++ ++ if (CreateThread(0, THREADSTACK, TimerThread, (void *) &sSeconds, 0, &ttid) == NULL) ++ return printf("Cannot create timer thread.\n"), -1; ++ ++ return 0; ++} ++ ++int StartTimer(TIMER *nStart) ++{ ++ if (!QueryPerformanceCounter(nStart)) ++ return printf("Timer error.\n"), -1; ++ ++ return 0; ++} ++ ++long StopTimer(TIMER *nStart, int nAccuracy) ++{ ++ TIMER nStop, nFreq; ++ ++ if (!QueryPerformanceCounter(&nStop)) ++ return printf("Timer error.\n"), -1; ++ if (!QueryPerformanceFrequency(&nFreq)) ++ return printf("Timer error.\n"), -1; ++ ++ nFreq.QuadPart = (nFreq.QuadPart + nAccuracy / 2) / nAccuracy; ++ ++ return (nStop.QuadPart - nStart->QuadPart) / nFreq.QuadPart; ++} ++ ++#endif /* WIN32 */ ++ ++#if defined(UNIX) || defined(DJGPP) ++ ++typedef struct timeval TIMER; ++ ++void on_alarm(int signum) ++{ ++ alarm(0); ++ bTimeOver = 1; ++} ++ ++int StartAlarm(long nSeconds) ++{ ++ bTimeOver = 0; ++ signal(SIGALRM, on_alarm); ++ alarm(nSeconds); ++ return 0; ++} ++ ++int StartTimer(TIMER *nStart) ++{ ++ struct timezone tz = {0, 0}; ++ ++ gettimeofday(nStart, &tz); ++ ++ return 0; ++} ++ ++long StopTimer(TIMER *nStart, int nAccuracy) ++{ ++ struct timezone tz = {0, 0}; ++ TIMER nStop; ++ ++ gettimeofday(&nStop, &tz); ++ ++ return (nStop.tv_sec - nStart->tv_sec) * nAccuracy ++ + (nStop.tv_usec - nStart->tv_usec) * nAccuracy / 1000000; ++} ++ ++#endif /* UNIX || DJGPP */ ++ ++/* initialize data to transfer */ ++ ++void GenerateRandomData(char *cBuffer, size_t nSize) ++{ ++ if (cBuffer != NULL) ++ { ++ size_t i; ++ ++ cBuffer[0] = 0; ++ srand(time(NULL)); ++ ++ for (i = 1; i < nSize; i++) ++ cBuffer[i] = (char) rand(); ++ } ++} ++ ++char *InitBuffer(size_t nSize) ++{ ++ char *cBuffer = malloc(nSize); ++ GenerateRandomData(cBuffer, nSize); ++ return cBuffer; ++} ++ ++char *PacketSize(int nSize) ++{ ++ static char szBuffer[64]; ++ ++ if ((nSize % 1024) == 0 || (nSize % 1024) == 1023) ++ sprintf(szBuffer, "%2dk", (nSize + 512) / 1024); ++ else ++ sprintf(szBuffer, "%d", nSize); ++ ++ return szBuffer; ++} ++ ++/* print results */ ++ ++typedef enum {nf_auto, nf_bytes, nf_kbytes, nf_mbytes, nf_gbytes} numberformat; ++numberformat nFormat = nf_auto; ++ ++void print_result(long long nData, long nTime) ++{ ++ numberformat nThisFormat = nFormat; ++ double nResult; ++ ++ if (nThisFormat == nf_auto) ++ { ++ if (nData < 10 * 1024 * INTERVAL) ++ nThisFormat = nf_bytes; ++ else if (nData < 10 * 1024 * 1024 * INTERVAL) ++ nThisFormat = nf_kbytes; ++ else if (nData < (long long) 1024 * 1024 * 1024 * INTERVAL) ++ nThisFormat = nf_mbytes; ++ else ++ nThisFormat = nf_gbytes; ++ } ++ ++ switch(nThisFormat) ++ { ++ case nf_bytes: ++ nResult = (double) nData * 1024 / nTime; ++ printf(" %0.0f Byte/s", nResult); ++ break; ++ ++ case nf_kbytes: ++ nResult = (double) nData / nTime; ++ printf(" %0.2f KByte/s", nResult); ++ break; ++ ++ case nf_mbytes: ++ nResult = (double) nData / nTime / 1024; ++ printf(" %0.2f MByte/s", nResult); ++ break; ++ ++ case nf_gbytes: ++ nResult = (double) nData / nTime / 1024 / 1024; ++ printf(" %0.3f GByte/s", nResult); ++ break; ++ } ++} ++ ++/* TCP/IP code */ ++ ++int send_data(int socket, void *buffer, size_t size, int flags) ++{ ++ int rc = send(socket, buffer, size, flags); ++ ++ if (rc < 0) ++ { ++ psock_errno("send()"); ++ return -1; ++ } ++ ++ if (rc != size) ++ return 1; ++ ++ return 0; ++} ++ ++int recv_data(int socket, void *buffer, size_t size, int flags) ++{ ++ ssize_t rc = recv(socket, buffer, size, flags); ++ ++ if (rc < 0) ++ { ++ psock_errno("recv()"); ++ return -1; ++ } ++ ++ if (rc != size) ++ return 1; ++ ++ return 0; ++} ++ ++const int sobufsize = 131072; ++int nPort = DEFAULTPORT; ++int nAuxPort = DEFAULTPORT + 1; ++#ifdef USE_IPV6 ++struct in6_addr addr_server; ++struct in6_addr addr_local; ++#else ++struct in_addr addr_server; ++struct in_addr addr_local; ++#endif ++ ++int udpsocket, udpd; ++unsigned long nUDPCount; ++long long nUDPData; ++ ++THREAD TCP_Server(void *arg) ++{ ++ char *cBuffer; ++ CONTROL ctl; ++ TIMER nTimer; ++ long nTime; ++ long long nData; ++#ifdef USE_IPV6 ++ struct sockaddr_in6 sa_server, sa_client; ++#else ++ struct sockaddr_in sa_server, sa_client; ++#endif ++ int server, client; ++ socklen_type length; ++ struct timeval tv; ++ fd_set fds; ++ int rc; ++ int nByte; ++ ++ if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) ++ { ++ perror("malloc()"); ++ return THREADRESULT; ++ } ++ ++#ifdef USE_IPV6 ++ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0) ++#else ++ if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) ++#endif ++ { ++ psock_errno("socket()"); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++#ifdef USE_IPV6 ++ sa_server.sin6_family = AF_INET6; ++ sa_server.sin6_port = htons(nPort); ++ sa_server.sin6_addr = addr_local; ++#else ++ sa_server.sin_family = AF_INET; ++ sa_server.sin_port = htons(nPort); ++ sa_server.sin_addr = addr_local; ++#endif ++ ++ if (bind(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0) ++ { ++ psock_errno("bind()"); ++ soclose(server); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ if (listen(server, 2) != 0) ++ { ++ psock_errno("listen()"); ++ soclose(server); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ for (;;) ++ { ++ printf("TCP server listening.\n"); ++ ++ FD_ZERO(&fds); ++ FD_SET(server, &fds); ++ tv.tv_sec = 3600; ++ tv.tv_usec = 0; ++ ++ if ((rc = select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0) ++ { ++ psock_errno("select()"); ++ break; ++ } ++ ++ if (rc == 0 || FD_ISSET(server, &fds) == 0) ++ continue; ++ ++ length = sizeof(sa_client); ++ if ((client = accept(server, (struct sockaddr *) &sa_client, &length)) == -1) ++ continue; ++ ++ setsockopt(client, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(client, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++ printf("TCP connection established ... "); ++ fflush(stdout); ++ ++ for (;;) ++ { ++ if (recv_data(client, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ ctl.cmd = ntohl(ctl.cmd); ++ ctl.data = ntohl(ctl.data); ++ ++ if (ctl.cmd == CMD_C2S) ++ { ++ StartTimer(&nTimer); ++ ++ printf("\nReceiving from client, packet size %s ... ", PacketSize(ctl.data)); ++ nData = 0; ++ ++ do ++ { ++ for (nByte = 0; nByte < ctl.data; ) ++ { ++ rc = recv(client, cBuffer + nByte, ctl.data - nByte, 0); ++ ++ if (rc < 0 && errno != EINTR) ++ { ++ psock_errno("recv()"); ++ break; ++ } ++ ++ if (rc > 0) ++ nByte += rc; ++ } ++ ++ nData += ctl.data; ++ } ++ while (cBuffer[0] == 0 && rc > 0); ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) != -1) ++ print_result(nData, nTime); ++ } ++ else if (ctl.cmd == CMD_S2C) ++ { ++ if (StartAlarm(INTERVAL) == 0) ++ { ++ StartTimer(&nTimer); ++ ++ printf("\nSending to client, packet size %s ... ", PacketSize(ctl.data)); ++ cBuffer[0] = 0; ++ nData = 0; ++ ++ while (!bTimeOver) ++ { ++ //GenerateRandomData(cBuffer, ctl.data); ++ ++ for (nByte = 0; nByte < ctl.data; ) ++ { ++ rc = send(client, cBuffer + nByte, ctl.data - nByte, 0); ++ ++ if (rc < 0 && errno != EINTR) ++ { ++ psock_errno("send()"); ++ break; ++ } ++ ++ if (rc > 0) ++ nByte += rc; ++ } ++ ++ nData += ctl.data; ++ } ++ ++ cBuffer[0] = 1; ++ ++ if (send_data(client, cBuffer, ctl.data, 0)) ++ break; ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) != -1) ++ print_result(nData, nTime); ++ } ++ } ++ else /* quit */ ++ break; ++ } ++ ++ printf("\nDone.\n"); ++ ++ soclose(client); ++ ++ if (rc < 0) ++ break; ++ } ++ ++ soclose(server); ++ free(cBuffer); ++ ++ return THREADRESULT; ++} ++ ++void TCP_Bench(void *arg) ++{ ++ char *cBuffer; ++ CONTROL ctl; ++ TIMER nTimer; ++ long nTime; ++ long long nData; ++ int i; ++#ifdef USE_IPV6 ++ struct sockaddr_in6 sa_server, sa_client; ++#else ++ struct sockaddr_in sa_server, sa_client; ++#endif ++ int server; ++ int rc; ++ int nByte; ++ ++ if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) ++ { ++ perror("malloc()"); ++ return; ++ } ++ ++#ifdef USE_IPV6 ++ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0) ++#else ++ if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) ++#endif ++ { ++ psock_errno("socket()"); ++ free(cBuffer); ++ return; ++ } ++ ++ setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++#ifdef USE_IPV6 ++ sa_client.sin6_family = AF_INET6; ++ sa_client.sin6_port = htons(0); ++ sa_client.sin6_addr = addr_local; ++#else ++ sa_client.sin_family = AF_INET; ++ sa_client.sin_port = htons(0); ++ sa_client.sin_addr = addr_local; ++#endif ++ ++ if (bind(server, (struct sockaddr *) &sa_client, sizeof(sa_client)) < 0) ++ { ++ psock_errno("bind()"); ++ soclose(server); ++ free(cBuffer); ++ return; ++ } ++ ++#ifdef USE_IPV6 ++ sa_server.sin6_family = AF_INET6; ++ sa_server.sin6_port = htons(nPort); ++ sa_server.sin6_addr = addr_server; ++#else ++ sa_server.sin_family = AF_INET; ++ sa_server.sin_port = htons(nPort); ++ sa_server.sin_addr = addr_server; ++#endif ++ ++ if (connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0) ++ { ++ psock_errno("connect()"); ++ soclose(server); ++ free(cBuffer); ++ return; ++ } ++ ++ printf("\nTCP connection established.\n"); ++ ++ for (i = 0; i < ntSizes; i++) ++ { ++ printf("Packet size %s bytes: ", PacketSize(tSizes[i])); ++ fflush(stdout); ++ ++ /* tell the server we will send it data now */ ++ ++ ctl.cmd = htonl(CMD_C2S); ++ ctl.data = htonl(tSizes[i]); ++ ++ if (send_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ /* 1 - Tx test */ ++ ++ if (StartAlarm(INTERVAL) == 0) ++ { ++ StartTimer(&nTimer); ++ nData = 0; ++ cBuffer[0] = 0; ++ ++ while (!bTimeOver) ++ { ++ //GenerateRandomData(cBuffer, tSizes[i]); ++ ++ for (nByte = 0; nByte < tSizes[i]; ) ++ { ++ rc = send(server, cBuffer + nByte, tSizes[i] - nByte, 0); ++ ++ if (rc < 0 && errno != EINTR) ++ { ++ psock_errno("send()"); ++ break; ++ } ++ ++ if (rc > 0) ++ nByte += rc; ++ } ++ ++ nData += tSizes[i]; ++ } ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) == -1) ++ printf(" (failed)"); ++ else ++ print_result(nData, nTime); ++ ++ printf(" Tx, "); ++ fflush(stdout); ++ ++ cBuffer[0] = 1; ++ ++ if (send_data(server, cBuffer, tSizes[i], 0)) ++ break; ++ } ++ ++ /* tell the server we expect him to send us data now */ ++ ++ ctl.cmd = htonl(CMD_S2C); ++ ctl.data = htonl(tSizes[i]); ++ ++ if (send_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ /* 2 - Rx test */ ++ ++ StartTimer(&nTimer); ++ nData = 0; ++ ++ do ++ { ++ for (nByte = 0; nByte < tSizes[i]; ) ++ { ++ rc = recv(server, cBuffer + nByte, tSizes[i] - nByte, 0); ++ ++ if (rc < 0 && errno != EINTR) ++ { ++ psock_errno("recv()"); ++ break; ++ } ++ ++ if (rc > 0) ++ nByte += rc; ++ } ++ ++ nData += tSizes[i]; ++ } ++ while (cBuffer[0] == 0 && rc > 0); ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) == -1) ++ printf(" (failed)"); ++ else ++ print_result(nData, nTime); ++ ++ printf(" Rx.\n"); ++ } ++ ++ ctl.cmd = htonl(CMD_QUIT); ++ ctl.data = 0; ++ ++ send_data(server, (void *) &ctl, CTLSIZE, 0); ++ ++ printf("Done.\n"); ++ ++ soclose(server); ++ free(cBuffer); ++} ++ ++THREAD UDP_Receiver(void *arg) ++{ ++ char *cBuffer; ++#ifdef USE_IPV6 ++ struct sockaddr_in6 sa_server, sa_client; ++#else ++ struct sockaddr_in sa_server, sa_client; ++#endif ++ int rc; ++ socklen_type nBytes; ++ ++ if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) ++ { ++ perror("malloc()"); ++ return THREADRESULT; ++ } ++ ++#ifdef USE_IPV6 ++ if ((udpsocket = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) ++#else ++ if ((udpsocket = socket(PF_INET, SOCK_DGRAM, 0)) < 0) ++#endif ++ { ++ psock_errno("socket(DGRAM)"); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ setsockopt(udpsocket, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(udpsocket, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++#ifdef USE_IPV6 ++ sa_server.sin6_family = AF_INET6; ++ sa_server.sin6_port = htons(nAuxPort); ++ sa_server.sin6_addr = addr_local; ++#else ++ sa_server.sin_family = AF_INET; ++ sa_server.sin_port = htons(nAuxPort); ++ sa_server.sin_addr = addr_local; ++#endif ++ ++ if (bind(udpsocket, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0) ++ { ++ psock_errno("bind(DGRAM)"); ++ soclose(udpsocket); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ udpd = 1; ++ ++ for (;;) ++ { ++ nBytes = sizeof(sa_client); ++ rc = recvfrom(udpsocket, cBuffer, TMAXSIZE, 0, (struct sockaddr *) &sa_client, &nBytes); ++ ++ if (rc < 0 && errno != EINTR) ++ psock_errno("recvfrom()"); ++ ++ if (rc > 0) ++ { ++ nUDPCount++; ++ nUDPData += rc; ++ } ++ } ++ ++ soclose(udpsocket); ++ free(cBuffer); ++ ++ return THREADRESULT; ++} ++ ++THREAD UDP_Server(void *arg) ++{ ++ char *cBuffer; ++ CONTROL ctl; ++ TIMER nTimer; ++ long nTime; ++ long long nData; ++#ifdef USE_IPV6 ++ struct sockaddr_in6 sa_server, sa_client; ++#else ++ struct sockaddr_in sa_server, sa_client; ++#endif ++ int server, client; ++ struct timeval tv; ++ fd_set fds; ++ int rc, nByte; ++ socklen_type nLength; ++ ++ if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) ++ { ++ perror("malloc()"); ++ return THREADRESULT; ++ } ++ ++#ifdef USE_IPV6 ++ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0) ++#else ++ if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) ++#endif ++ { ++ psock_errno("socket(STREAM)"); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++#ifdef USE_IPV6 ++ sa_server.sin6_family = AF_INET6; ++ sa_server.sin6_port = htons(nAuxPort); ++ sa_server.sin6_addr = addr_local; ++#else ++ sa_server.sin_family = AF_INET; ++ sa_server.sin_port = htons(nAuxPort); ++ sa_server.sin_addr = addr_local; ++#endif ++ ++ if (bind(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0) ++ { ++ psock_errno("bind(STREAM)"); ++ soclose(server); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ if (listen(server, 2) != 0) ++ { ++ psock_errno("listen()"); ++ soclose(server); ++ free(cBuffer); ++ return THREADRESULT; ++ } ++ ++ for (;;) ++ { ++ printf("UDP server listening.\n"); ++ ++ FD_ZERO(&fds); ++ FD_SET(server, &fds); ++ tv.tv_sec = 3600; ++ tv.tv_usec = 0; ++ ++ if ((rc = select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0) ++ { ++ psock_errno("select()"); ++ break; ++ } ++ ++ if (rc == 0 || FD_ISSET(server, &fds) == 0) ++ continue; ++ ++ nLength = sizeof(sa_client); ++ if ((client = accept(server, (struct sockaddr *) &sa_client, &nLength)) == -1) ++ continue; ++ ++ setsockopt(client, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(client, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++ printf("UDP connection established ... "); ++ fflush(stdout); ++ ++#ifdef USE_IPV6 ++ sa_client.sin6_port = htons(nAuxPort); ++#else ++ sa_client.sin_port = htons(nAuxPort); ++#endif ++ ++ for (;;) ++ { ++ if (recv_data(client, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ ctl.cmd = ntohl(ctl.cmd); ++ ctl.data = ntohl(ctl.data); ++ ++ if (ctl.cmd == CMD_C2S) ++ { ++ StartTimer(&nTimer); ++ nUDPCount = 0; ++ nUDPData = 0; ++ ++ printf("\nReceiving from client, packet size %s ... ", PacketSize(ctl.data)); ++ ++ ctl.cmd = htonl(ctl.cmd); ++ ctl.data = htonl(ctl.data); ++ ++ if (send_data(client, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ } ++ else if (ctl.cmd == CMD_RES) ++ { ++ ctl.cmd = htonl(ctl.cmd); ++ ctl.data = htonl(nUDPCount); ++ ++ if (send_data(client, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) != -1) ++ print_result(nUDPData, nTime); ++ } ++ else if (ctl.cmd == CMD_S2C) ++ { ++ if (StartAlarm(INTERVAL) == 0) ++ { ++ StartTimer(&nTimer); ++ nData = 0; ++ ++ printf("\nSending to client, packet size %s ... ", PacketSize(ctl.data)); ++ cBuffer[0] = 0; ++ nLength = ctl.data; ++ ++ ctl.cmd = htonl(CMD_RES); ++ ctl.data = 0; ++ ++ while (!bTimeOver) ++ { ++ //GenerateRandomData(cBuffer, nLength); ++ ++ for (nByte = 0; nByte < nLength; ) ++ { ++ do ++ { ++ rc = sendto(udpsocket, cBuffer + nByte, nLength - nByte, 0, ++ (struct sockaddr *) &sa_client, sizeof(sa_client)); ++ } ++#ifdef ENOBUFS ++ while (rc < 0 && errno == ENOBUFS); ++#else ++ while (0); ++#endif ++ ++ if (rc < 0 && errno != EINTR) ++ { ++ psock_errno("sendto()"); ++ break; ++ } ++ ++ if (rc > 0) ++ nByte += rc; ++ } ++ ++ ctl.data++; ++ nData += nLength; ++ } ++ ++ ctl.data = htonl(ctl.data); ++ ++ if (send_data(client, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) != -1) ++ print_result(nData, nTime); ++ } ++ } ++ else /* quit */ ++ break; ++ } ++ ++ printf("\nDone.\n"); ++ ++ soclose(client); ++ ++ if (rc < 0) ++ break; ++ } ++ ++ soclose(server); ++ free(cBuffer); ++ ++ return THREADRESULT; ++} ++ ++void UDP_Bench(void *arg) ++{ ++ char *cBuffer; ++ CONTROL ctl; ++ TIMER nTimer; ++ long nTime, nCount; ++ long nResult; ++ long long nData; ++ int i; ++#ifdef USE_IPV6 ++ struct sockaddr_in6 sa_server, sa_client; ++#else ++ struct sockaddr_in sa_server, sa_client; ++#endif ++ int server; ++ int rc, nByte; ++ ++ if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) ++ { ++ perror("malloc()"); ++ return; ++ } ++ ++#ifdef USE_IPV6 ++ if ((server = socket(PF_INET6, SOCK_STREAM, 0)) < 0) ++#else ++ if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) ++#endif ++ { ++ psock_errno("socket()"); ++ free(cBuffer); ++ return; ++ } ++ ++ setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); ++ ++#ifdef USE_IPV6 ++ sa_client.sin6_family = AF_INET6; ++ sa_client.sin6_port = htons(0); ++ sa_client.sin6_addr = addr_local; ++#else ++ sa_client.sin_family = AF_INET; ++ sa_client.sin_port = htons(0); ++ sa_client.sin_addr = addr_local; ++#endif ++ ++ if (bind(server, (struct sockaddr *) &sa_client, sizeof(sa_client)) < 0) ++ { ++ psock_errno("bind(STREAM)"); ++ soclose(server); ++ free(cBuffer); ++ return; ++ } ++ ++#ifdef USE_IPV6 ++ sa_server.sin6_family = AF_INET6; ++ sa_server.sin6_port = htons(nAuxPort); ++ sa_server.sin6_addr = addr_server; ++#else ++ sa_server.sin_family = AF_INET; ++ sa_server.sin_port = htons(nAuxPort); ++ sa_server.sin_addr = addr_server; ++#endif ++ ++ if (connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server)) < 0) ++ { ++ psock_errno("connect()"); ++ soclose(server); ++ free(cBuffer); ++ return; ++ } ++ ++ printf("\nUDP connection established.\n"); ++ ++ for (i = 0; i < ntSizes; i++) ++ { ++ printf("Packet size %s bytes: ", PacketSize(tSizes[i])); ++ fflush(stdout); ++ ++ /* tell the server we will send it data now */ ++ ++ ctl.cmd = htonl(CMD_C2S); ++ ctl.data = htonl(tSizes[i]); ++ ++ if (send_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ if (recv_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ /* 1 - Tx test */ ++ ++ if (StartAlarm(INTERVAL) == 0) ++ { ++ StartTimer(&nTimer); ++ nData = 0; ++ nCount = 0; ++ cBuffer[0] = 0; ++ ++ while (!bTimeOver) ++ { ++ //GenerateRandomData(cBuffer, tSizes[i]); ++ ++ for (nByte = 0; nByte < tSizes[i]; ) ++ { ++ rc = sendto(udpsocket, cBuffer + nByte, tSizes[i] - nByte, 0, ++ (struct sockaddr *) &sa_server, sizeof(sa_server)); ++ ++ if (rc < 0) ++ { ++ if (errno != EINTR) ++ { ++ psock_errno("sendto()"); ++ break; ++ } ++ } ++ else ++ nByte += rc; ++ } ++ ++ nData += tSizes[i]; ++ nCount++; ++ } ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) == -1) ++ printf(" (failed)"); ++ ++ ctl.cmd = htonl(CMD_RES); ++ ++ if (send_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ if (recv_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ ctl.data = ntohl(ctl.data); ++ nData = (long long) tSizes[i] * ctl.data; ++ ++ print_result(nData, nTime); ++ nResult = (nCount - ctl.data) * 100 / nCount; ++ printf(" (%ld%%) Tx, ", nResult); ++ fflush(stdout); ++ } ++ ++ /* tell the server we expect him to send us data now */ ++ ++ ctl.cmd = htonl(CMD_S2C); ++ ctl.data = htonl(tSizes[i]); ++ ++ if (send_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ /* 2 - Rx test */ ++ ++ StartTimer(&nTimer); ++ nUDPCount = 0; ++ nUDPData = 0; ++ ++ if (recv_data(server, (void *) &ctl, CTLSIZE, 0)) ++ break; ++ ++ if ((nTime = StopTimer(&nTimer, 1024)) == -1) ++ printf(" (failed)"); ++ ++ ctl.data = ntohl(ctl.data); ++ ++ print_result(nUDPData, nTime); ++ nResult = (ctl.data - nUDPCount) * 100 / ctl.data; ++ printf(" (%ld%%) Rx.\n", nResult); ++ } ++ ++ ctl.cmd = htonl(CMD_QUIT); ++ ctl.data = 0; ++ ++ send_data(server, (void *) &ctl, CTLSIZE, 0); ++ ++ printf("Done.\n"); ++ ++ soclose(server); ++ free(cBuffer); ++} ++ ++/* main / user interface */ ++ ++int bSRV, bTCP, bUDP; ++ ++void handler(int sig) ++{ ++ _exit(0); ++} ++ ++void usage(void) ++{ ++ printf( ++ "\nUsage: netio [options] [<server>]\n" ++ "\n -s run server side of benchmark (otherwise run client)" ++ "\n -b <size>[k] use this block size (otherwise run with 1,2,4,8,16 and 32k)" ++ "\n -B -K -M -G force number formatting to Bytes, K, M or G Bytes\n" ++ ++ "\n -t use TCP protocol for benchmark" ++ "\n -u use UDP protocol for benchmark" ++ "\n -h <addr/name> bind TCP and UDP sockets to this local host address/name" ++ "\n defaults to all (server) or unspecified (client)" ++ "\n -p <port> bind TCP and UDP servers to this port (default is %d)\n" ++ ++ "\n <server> If the client side of the benchmark is running," ++ "\n a server name or address is required.\n" ++ ++ "\nThe server side can run either TCP (-t) or UDP (-u) protocol or both" ++ "\n(default, if neither -t or -u is specified). The client runs one of" ++ "\nthese protocols only (must specify -t or -u).\n" ++ "\n", nPort); ++ exit(1); ++} ++ ++int main(int argc, char **argv) ++{ ++ char szVersion[32], *szName = 0, *szLocal = 0, *szEnd; ++ int option; ++ struct hostent *host; ++ long nSize; ++ ++ strcpy(szVersion, rcsrev + sizeof("$Revision: ") - 1); ++ *strchr(szVersion, ' ') = 0; ++ ++ printf("\nNETIO - Network Throughput Benchmark, Version %s" ++ "\n(C) 1997-2012 Kai Uwe Rommel\n", szVersion); ++ ++ if (argc == 1) ++ usage(); ++ ++ /* check arguments */ ++ ++ while ((option = getopt(argc, argv, "?stup:h:b:dBKMG")) != -1) ++ switch (option) ++ { ++ case 's': ++ bSRV = 1; ++ break; ++ case 't': ++ bTCP = 1; ++ break; ++ case 'u': ++ bUDP = 1; ++ break; ++ case 'p': ++ nPort = atoi(optarg); ++ nAuxPort = nPort + 1; ++ break; ++ case 'h': ++ szLocal = optarg; ++ break; ++ case 'b': ++ nSize = strtol(optarg, &szEnd, 10); ++ if (*szEnd == 'k') ++ nSize *= 1024; ++ nSizes[0] = min(max(nSize, 1), NMAXSIZE); ++ tSizes[0] = min(max(nSize, 1), TMAXSIZE); ++ nnSizes = ntSizes = 1; ++ break; ++#ifdef WATT32 ++ case 'd': ++ dbug_init(); ++ break; ++#endif ++ case 'B': ++ nFormat = nf_bytes; ++ break; ++ case 'K': ++ nFormat = nf_kbytes; ++ break; ++ case 'M': ++ nFormat = nf_mbytes; ++ break; ++ case 'G': ++ nFormat = nf_gbytes; ++ break; ++ default: ++ usage(); ++ break; ++ } ++ ++ if (bSRV == 1 && bTCP == 0 && bUDP == 0) ++ bTCP = bUDP = 1; ++ ++ /* initialize TCP/IP */ ++ ++ if (bTCP || bUDP) ++ { ++ if (sock_init()) ++ return psock_errno("sock_init()"), 1; ++ ++ if (szLocal == 0) ++#ifdef USE_IPV6 ++ addr_local = in6addr_any; ++#else ++ addr_local.s_addr = INADDR_ANY; ++#endif ++ else ++ { ++ if (isdigit(*szLocal)) ++#ifdef USE_IPV6 ++ inet_pton(AF_INET6, szLocal, &addr_local); ++#else ++ addr_local.s_addr = inet_addr(szLocal); ++#endif ++ else ++ { ++ if ((host = gethostbyname(szLocal)) == NULL) ++ return psock_errno("gethostbyname()"), 1; ++ ++#ifdef USE_IPV6 ++ addr_local = * (struct in6_addr *) (host->h_addr); ++#else ++ addr_local = * (struct in_addr *) (host->h_addr); ++#endif ++ } ++ } ++ ++ if (!bSRV) ++ { ++ if (optind == argc) ++ usage(); ++ ++ if (isdigit(*argv[optind])) ++#ifdef USE_IPV6 ++ inet_pton(AF_INET6, argv[optind], &addr_server); ++#else ++ addr_server.s_addr = inet_addr(argv[optind]); ++#endif ++ else ++ { ++ if ((host = gethostbyname(argv[optind])) == NULL) ++ return psock_errno("gethostbyname()"), 1; ++ ++#ifdef USE_IPV6 ++ addr_server = * (struct in6_addr *) (host->h_addr); ++#else ++ addr_server = * (struct in_addr *) (host->h_addr); ++#endif ++ } ++ } ++ } ++ ++ /* do work */ ++ ++ signal(SIGINT, handler); ++ ++ if (bSRV) ++ { ++ printf("\n"); ++ ++ if (bTCP) ++ { ++ if (newthread(TCP_Server)) ++ return printf("Cannot create additional thread.\n"), 2; ++ } ++ if (bUDP) ++ { ++ if (newthread(UDP_Receiver)) ++ return printf("Cannot create additional thread.\n"), 2; ++ if (newthread(UDP_Server)) ++ return printf("Cannot create additional thread.\n"), 2; ++ } ++ ++ for (;;) sleep(86400); ++ } ++ else ++ { ++ if (bTCP + bUDP > 1) /* exactly one only */ ++ usage(); ++ ++ if (bTCP) ++ TCP_Bench(0); ++ else if (bUDP) ++ { ++ if (newthread(UDP_Receiver)) ++ return printf("Cannot create additional thread.\n"), 2; ++ while (udpd == 0) sleep(1); ++ UDP_Bench(0); ++ } ++ } ++ ++ /* terminate */ ++ ++ printf("\n"); ++ ++ return 0; ++} ++ ++/* end of netio.c */ ++ |