From 902e1e1c72d9ed1a4aee70497ad00560755e8d50 Mon Sep 17 00:00:00 2001 From: Bartek Rutkowski Date: Sun, 22 Mar 2015 17:28:27 +0000 Subject: benchmarks/netio: update 1.26 -> 1.32 - Fix clang build issues - Maintainer's timeout (arved@FreeBSD.org) PR: 181789 Submitted by: Pawel Biernacki --- benchmarks/netio/Makefile | 6 +- benchmarks/netio/distinfo | 4 +- benchmarks/netio/files/patch-netio.c | 3408 +++++++++++++++++++++++++++++++--- 3 files changed, 3131 insertions(+), 287 deletions(-) (limited to 'benchmarks/netio') 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 +- * 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 +- * +- * +- * Revision 1.8 1999/10/12 11:02:00 giva +- * added Watt-32 with djgpp support. Added debug mode. +- * G. Vanem +- * +- * Revision 1.7 1999/06/13 18:42:25 rommel +- * added Linux port with patches from Detlef Plotzky +- * +- * Revision 1.6 1998/10/12 11:14:58 rommel +- * change to malloc'ed (and tiled) memory for transfer buffers +- * (hint from Guenter Kukkukk ) +- * 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 +-#include +-#include +-#include +-#include +-#if defined(UNIX) || defined(DJGPP) +-#include +-#include +-#include +-#else +-#include +-#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 +-#include +-#include +-#include +-#include +-#include +- +-#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 /* sock_init() etc. */ +-#include +-#include +-#include +-#define soclose close_s +-#define select select_s +-#define psock_errno perror +- +-#endif /* WATT32 */ +- +-#ifdef WIN32 +- +-#include +-#include +-#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 +-#include +-#include +-#include +-#include +-#include +- +-#define psock_errno(x) perror(x) +-#define soclose(x) close(x) +- +-int sock_init(void) +-{ +- return 0; +-} +- +-#include +-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 +- +-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] []\n" +- "\n -s run server side of benchmark (otherwise run client)" +- "\n -b [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 bind TCP and UDP sockets to this local host address/name" +- "\n defaults to all (server) or unspecified (client)" +- "\n -p bind TCP and UDP servers to this port (default is %d)\n" +- +- "\n 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 ++ * 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 ++ * ++ * ++ * Revision 1.8 1999/10/12 11:02:00 giva ++ * added Watt-32 with djgpp support. Added debug mode. ++ * G. Vanem ++ * ++ * Revision 1.7 1999/06/13 18:42:25 rommel ++ * added Linux port with patches from Detlef Plotzky ++ * ++ * Revision 1.6 1998/10/12 11:14:58 rommel ++ * change to malloc'ed (and tiled) memory for transfer buffers ++ * (hint from Guenter Kukkukk ) ++ * 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 ++#include ++#include ++#include ++#include ++#if defined(UNIX) || defined(DJGPP) ++#include ++#include ++#include ++#include ++#else ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 /* sock_init() etc. */ ++#include ++#include ++#include ++#define soclose close_s ++#define select select_s ++#define psock_errno perror ++ ++#endif /* WATT32 */ ++ ++#ifdef WIN32 ++ ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++ ++#define psock_errno(x) perror(x) ++#define soclose(x) close(x) ++ ++int sock_init(void) ++{ ++ return 0; ++} ++ ++#include ++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 ++ ++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] []\n" ++ "\n -s run server side of benchmark (otherwise run client)" ++ "\n -b [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 bind TCP and UDP sockets to this local host address/name" ++ "\n defaults to all (server) or unspecified (client)" ++ "\n -p bind TCP and UDP servers to this port (default is %d)\n" ++ ++ "\n 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 */ ++ -- cgit v1.2.3