We no longer offer ftp downloads. If there is a file you need referenced here, please contact me by email and I will get it to you.
Kevin Smith of Shade Tree Software, Inc. is a frequent contributor to the SCO newsgroups. Here he provides a small utility to exercise and test network ports. You can download the source or an OSR5 binary.
To compile the source:
cc nettest.c -o nettest -lsocket
For the most simple test, run "nettest -r", switch to another virtual console and run "nettest -w". Switch back to see the results.
Download Source.
Download OSR5 binary.
I've been sitting on a utility to test network connectivity and throughput for a while now and thought some others might be interested.
The program is called 'nettest'. It runs in one of four modes.
TCP (normal connection type mode)
Accepts multiple connections, reads and discards data. Reports transfer stats when a connection closes.
UDP (connectionless datagrams)
This is connectionless so it just reports stats every now and
then (every MB)
TCP
UDP
Both of these write N buffers of N bytes each to a given hostname and port and report transfer stats. It was originally written as four separate programs so the code is a little rough in spots...
---- Cut Here --------------------------------------------------------
/*
* @(#)nettest.c--Test read and writes to a network port
*/
static char *what[]={
"@(#)nettest--Test reads/writes to a network port",
"@(#)Copyright 2000 ShadeTree Software,Inc.",
"@(#)Any and all uses allowed, no responsibility accepted :)",
"@(#)STS/KBS 2apr1996",
0,
};
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/times.h>
#include <netdb.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#define M_NONE 0
#define M_READ 1
#define M_WRITE 2
#define MN_NONE 0
#define MN_TCPIP 1
#define MN_UDP 2
int debugl;
char *iam;
int rwmode = M_NONE;
int netmode = MN_TCPIP;
char *hostname = "localhost";
int port = 10001;
int bufsz = 1024;
int nbufs = 100;
char ebuf[512]; /* error messages */
int hz; /* for timings */
extern int h_errno;
main(ac,av)
int ac;
char *av[];
{
int s;
struct sockaddr_in sin;
int c;
struct hostent *hp;
char *buf;
int bufr,bufw;
int oc; /* current option char */
int on; /* current string option number */
extern char *optarg; /* stuff for getopt */
extern int optind, optopt; /* stuff for getopt */
iam = av[0];
hz = sysconf(_SC_CLK_TCK);
on = 0;
while(( oc = getopt(ac,av,"urwdb:n:h:p:")) != -1 )
{
switch(oc)
{
case 'u':
netmode = MN_UDP;
break;
case 'r':
if (rwmode != M_NONE)
{
usage();
}
rwmode = M_READ;
break;
case 'w':
if (rwmode != M_NONE)
{
usage();
}
rwmode = M_WRITE;
break;
case 'd':
debugl++;
break;
case 'b':
bufsz = atoi(optarg);
break;
case 'n':
nbufs = atoi(optarg);
break;
case 'h':
hostname = optarg;
break;
case 'p':
port = atoi(optarg);
break;
case ':':
case '?':
default:
usage();
break;
}
}
if(optind < ac)
{
fprintf(stderr,"Too many arguments (%s)\n",av[optind]);
usage();
}
if(rwmode == M_NONE)
{
fprintf(stderr,"One of -r or -w is manditory\n");
usage();
}
if(debugl)
{
fprintf(
stderr,
"mode = %s %s\n",
netmode == MN_NONE ? "None" :
netmode == MN_TCPIP ? "TCP/IP" :
netmode == MN_UDP ? "UDP" : "???",
rwmode == M_NONE ? "None" :
rwmode == M_READ ? "Read" :
rwmode == M_WRITE ? "Write" : "???"
);
fprintf(stderr,"bufsz = %d\n",bufsz);
fprintf(stderr,"nbufs = %d\n",nbufs);
fprintf(stderr,"hostname = %s\n",hostname);
fprintf(stderr,"port = %d\n",port);
}
if (netmode == MN_TCPIP)
{
if (rwmode == M_WRITE)
{
return(tcpwrite());
}
else
{
return(tcpread());
}
}
else
{
if (rwmode == M_WRITE)
{
return(udpwrite());
}
else
{
return(udpread());
}
}
/* NOTREACHED */
}
int
tcpwrite(void)
{
int s;
struct sockaddr_in sin;
int c;
struct hostent *hp;
char *buf;
int bufr,bufw;
int stime, etime, totalwrites, totalbytes;
struct tms tms;
if(!(buf=malloc(bufsz))) {
perror("malloc()");
return;
}
setbuf(stderr,NULL);
hp = gethostbyname(hostname);
if(debugl) fprintf(stderr,"gethostbyname()=0x%x\n",hp);
if(!hp) {
herror(hostname);
return(2);
}
for(;;) {
s=socket(AF_INET, SOCK_STREAM, 0);
if(debugl) fprintf(stderr,"socket()=%d\n",s);
if(s<0) {
perror("Can't open socket");
return(2);
}
/*
* Build socket name
*/
memset(&sin,0,sizeof(sin));
memcpy( (char *)&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
sin.sin_family = hp->h_addrtype;
sin.sin_port = htons(port);
if(debugl) fprintf(stderr,"sin.sin_addr=%s\n",inet_ntoa(sin.sin_addr));
c=connect(s,(struct sockaddr *)&sin,sizeof(sin));
if(debugl) fprintf(stderr,"connect()=%d\n",c);
if(c) {
if(debugl) {
sprintf(buf,"Connect to port %d on %s",port,hostname);
perror(buf);
}
close(s);
sleep(5);
} else {
break;
}
}
if(fcntl(s, F_SETFL, fcntl(s,F_GETFL,0) & O_SYNC) == -1) {
if(debugl) perror("fcntl(O_SYNC)");
}
buf[0] = '\n';
stime = etime = times(&tms);
totalwrites = totalbytes = 0;
for(c=0; c<nbufs;c++) {
bufr = bufsz;
bufw=write(s,buf,bufr);
if(debugl) fprintf(stderr,"write()=%d\n",bufw);
if(bufr != bufw) {
if(debugl) fprintf(stderr,"short write!\n");
if(bufw < 0) break;
}
totalwrites++;
totalbytes += bufw;
}
/* show stats */
etime = times(&tms);
{
float bps,secs;
secs = etime - stime;
secs /= hz;
if(secs > 0)
{
bps = (float)totalbytes / secs;
}
else
{
bps = 0;
}
fprintf(
stderr,
"%d writes, %d bytes in %g seconds, %.0f bps\n",
totalwrites,
totalbytes,
secs,
bps
);
}
close(s);
return(0);
}
int
tcpread(void)
{
struct sockaddr_in sin; /* socket name */
int s; /* our socket */
int sc; /* incomming connection socket */
struct sockaddr_in sf; /* socket name of connection */
int sflen; /* socket name length */
fd_set allmask; /* initial select mask (our socket) */
fd_set rmask; /* current select mask (w connects) */
int sv; /* select return value */
int rz; /* read size */
int one = 1;
char *buf;
struct tms tms;
struct {
clock_t stime;
clock_t etime;
int currentbytes; /* used for status updates */
int totalreads;
int totalbytes;
} ss[20];
if(!(buf=malloc(bufsz))) {
perror("malloc()");
return;
}
/*
* Create the socket (file descriptor)
* Give up immediatly if we can't get a socket.
*/
if((s=socket(AF_INET,SOCK_STREAM,0))<0) {
perror("Couldn't create socket");
return(1);
}
fprintf(stderr,"Created socket %d\n",s);
/*
* Reuse port--Easy testing
*/
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one))) {
perror("setsockopt");
}
/*
* Build socket name
*/
memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
/*
* Bind to socket
*/
if(bind(s, (struct sockaddr *)&sin, sizeof(sin))) {
sprintf(
ebuf,
"Couldn't bind to port %d",
ntohs(sin.sin_port)
);
perror(ebuf);
close(s);
return(1);
}
fprintf(
stderr,
"Bound to port %d\n",
ntohs(sin.sin_port)
);
/*
* Estabilish connection queue
*/
listen(s,5);
/*
* Setup select mask.
* Initialize to our socket only
*/
FD_ZERO(&allmask);
FD_SET(s,&allmask);
/*
* Wait for activity
*/
for(;;) {
if(debugl) fprintf(stderr,"Waiting...");
memcpy(&rmask,&allmask,sizeof(allmask));
sv = select(20,&rmask,0,0,0);
if(debugl) putc(' ',stderr);
if(sv<0) {
perror("select");
continue;
}
/*
* Check for connection attempt (our socket)
*/
if(FD_ISSET(s,&rmask)) {
fprintf(stderr,"Incomming connection...\n");
FD_CLR(s,&rmask); /* Clear ourselvs from current set */
sflen = sizeof(struct sockaddr_in);
sc = accept(s,(struct sockaddr*)&sf, &sflen);
if(sc<0) {
perror("accept");
continue;
}
fprintf(
stderr,
" socket=%d, ip=%s, port=%d\n",
sc,
inet_ntoa(sf.sin_addr),
ntohs(sf.sin_port)
);
FD_SET(sc,&allmask); /* Add to active set */
ss[sc].stime = times(&tms);
ss[sc].etime = ss[sc].stime;
ss[sc].totalreads = 0;
ss[sc].totalbytes = 0;
}
/*
* Check for other activity
*/
for(sc = 3; sc < 20; sc++) {
if(FD_ISSET(sc,&rmask)) {
FD_CLR(sc,&rmask);
errno = 0;
rz = read(sc,buf,bufsz);
if(rz>0) {
ss[sc].totalreads++;
ss[sc].totalbytes += rz;
if(debugl) {
fprintf(
stderr,
"(%d) read()=%d (errno=%d), total=%d\n",
sc,rz,errno,ss[sc].totalbytes
);
} else {
ss[sc].currentbytes += rz;
if(ss[sc].currentbytes >= 1000000) {
fprintf(stderr,"\r(%d) %d ",sc,ss[sc].totalbytes);
ss[sc].currentbytes = 0;
}
}
}
if(rz <= 0) {
fprintf(stderr,"\r(%d) %d ",sc,ss[sc].totalbytes);
if(rz==0) {
fprintf(stderr,"EOF--disconnecting\n");
} else {
perror("read from socket--disconnecting");
}
ss[sc].etime = times(&tms);
close(sc);
FD_CLR(sc,&allmask);
{
float bps,secs;
secs = ss[sc].etime - ss[sc].stime;
secs /= hz;
if(secs > 0)
{
bps = (float)ss[sc].totalbytes / secs;
}
else
{
bps = 0;
}
fprintf(
stderr,
"(%d) %d reads, %d bytes in %g seconds, %.0f bps\n",
sc,
ss[sc].totalreads,
ss[sc].totalbytes,
secs,
bps
);
}
continue;
}
}
}
}
}
int
udpwrite(void)
{
int s;
struct sockaddr_in sin;
int c;
struct hostent *hp;
char *buf;
int bufr;
int stime, etime, totalwrites, totalbytes;
struct tms tms;
if(!(buf=malloc(bufsz))) {
perror("malloc()");
return;
}
setbuf(stderr,NULL);
hp = gethostbyname(hostname);
if(debugl) fprintf(stderr,"gethostbyname()=0x%x\n",hp);
if(!hp) {
herror(hostname);
return(2);
}
s=socket(AF_INET, SOCK_DGRAM, 0);
if(debugl) fprintf(stderr,"socket()=%d\n",s);
if(s<0) {
perror("Can't open socket");
return(2);
}
/*
* Build socket name
*/
memset(&sin,0,sizeof(sin));
memcpy( (char *)&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
sin.sin_family = hp->h_addrtype;
sin.sin_port = htons(port);
if(debugl) fprintf(stderr,"sin.sin_addr=%s\n",inet_ntoa(sin.sin_addr));
buf[0] = '\n';
stime = etime = times(&tms);
totalwrites = totalbytes = 0;
for(c=0; c<nbufs;c++) {
bufr = bufsz;
if(
sendto(
s,
(void *)buf,
bufr,
0,
(struct sockaddr *)&sin,sizeof(sin)
) < 0
)
{
perror("sendto()");
} else {
if(debugl) fprintf(stderr,"sendto(%d,0x%x,%d)\n",s,buf,bufr);
totalwrites++;
totalbytes += bufr;
}
}
/* show stats */
etime = times(&tms);
{
float bps,secs;
secs = etime - stime;
secs /= hz;
if(secs > 0)
{
bps = (float)totalbytes / secs;
}
else
{
bps = 0;
}
fprintf(
stderr,
"%d writes, %d bytes in %g seconds, %.0f bps\n",
totalwrites,
totalbytes,
secs,
bps
);
}
close(s);
return(0);
}
int
udpread(void)
{
struct sockaddr_in sin; /* socket name */
int s; /* our socket */
int rz; /* read size */
int one = 1;
char *buf;
int currentreads, currentbytes;
int stime, etime, totalreads, totalbytes;
struct tms tms;
if(!(buf=malloc(bufsz))) {
perror("malloc()");
return;
}
/*
* Create the socket (file descriptor)
* Give up immediatly if we can't get a socket.
*/
if((s=socket(AF_INET,SOCK_DGRAM,0))<0) {
perror("Couldn't create socket");
return(1);
}
fprintf(stderr,"Created socket %d\n",s);
/*
* Reuse port--Easy testing
*/
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one))) {
perror("setsockopt");
}
/*
* Build socket name
*/
memset(&sin,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
/*
* Bind to socket
*/
if(bind(s, (struct sockaddr *)&sin, sizeof(sin))) {
sprintf(
ebuf,
"Couldn't bind to port %d",
ntohs(sin.sin_port)
);
perror(ebuf);
close(s);
return(1);
}
fprintf(
stderr,
"Bound to port %d\n",
ntohs(sin.sin_port)
);
currentreads = currentbytes = totalbytes = totalreads = 0;
stime = etime = times(&tms);
for(;;) {
if(debugl) fprintf(stderr,"Waiting...");
rz = read(s,buf,bufsz);
if(rz>0) {
currentbytes += rz;
currentreads++;
totalbytes += rz;
totalreads++;
if(debugl) {
fprintf(
stderr,
"(%d) read()=%d (errno=%d), total=%d\n",
s,rz,errno,totalbytes
);
}
if(currentbytes >= 1000000) {
/* show stats */
etime = times(&tms);
{
float bps,secs;
secs = etime - stime;
secs /= hz;
if(secs > 0)
{
bps = (float)currentbytes / secs;
}
else
{
bps = 0;
}
fprintf(
stderr,
"%d reads, %d bytes in %g seconds, %.0f bps\n",
currentreads,
currentbytes,
secs,
bps
);
}
currentreads = currentbytes = 0;
stime = etime;
}
}
if(rz <= 0) {
fprintf(stderr,"\r(%d) %d ",s,totalbytes);
if(rz==0) {
fprintf(stderr,"EOF--disconnecting\n");
} else {
perror("read from socket--disconnecting");
}
}
}
}
int
usage(void)
{
fprintf(
stderr,
"usage: %s {-r|-w} [-u] [-d] [-hhostname] [-pportnumber] [-bbufsz] [-nnbufs]\n",
iam
);
fprintf(stderr," -r (read) or -w (write) manditory/exclusive\n");
fprintf(stderr," -u for UDP packets\n");
fprintf(stderr," -d enables debug messages\n");
fprintf(stderr," Default hostname is %s\n",hostname);
fprintf(stderr," Default port is %d\n",port);
fprintf(stderr," Default bufsz is %d\n",bufsz);
fprintf(stderr," Default nbufs is %d\n",nbufs);
fprintf(stderr," Note: hostname,nbufs ignored if not -r\n");
exit(1);
}
---- Cut Here --------------------------------------------------------
Download Source.
Download OSR5 binary.
Publish your articles, comments, book reviews or opinions here!
© January 2000 Shade Tree Software, Inc.
More Articles by Shade Tree Software Inc
/Unix/nettest.html copyright January 2000 Shade Tree Software Inc All Rights Reserved
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.
Click here to add your comments
Don't miss responses! Subscribe to Comments by RSS or by Email
Click here to add your comments
If you want a picture to show with your comment, go get a Gravatar