static void tcp_echo(
char * host, char * service, unsigned size, unsigned iters) {
char * str = new char[size];
char * bfr = new char[size];
for (unsigned i = 0; i < iters; i++) {
gettimeofday(&start, NULL);
int s = tcp_connect(host, service);
write(s, str, size);
tcp_read(s, bfr, size);
shutdown(s, 1);
close(s);
gettimeofday(&stop, NULL);
}
}
const unsigned buffer_size = 1024*16;
static char buffer[buffer_size];
static void echo(int s) {
int cc;
do {
cc = read(s, buffer, sizeof(buffer));
write(s, buffer, cc);
}
while (cc > 0);
}
int main(int argc, char * argv[]) {
const int ms = passive_tcp(opts['s'], tcp_qlen);
while (true) {
const int s = accept_tcp(ms);
echo(s);
close(s);
}
return EXIT_SUCCESS;
}
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 12 req/sec, 500.4 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 267.6 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 267.2 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 181.1 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 178.2 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 178.7 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 137.7 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 136.8 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 134.5 kbytes/sec. cs18 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 136.8 kbytes/sec.
shutdown() doesn't work.
shutdown() doesn't recover resources; close() does.
const unsigned buffer_size = 1024*16;
static char buffer[buffer_size];
static void echo(int s) {
int cc;
while ((cc = read(s, buffer, sizeof(buffer))) > 0)
write(s, buffer, cc);
close(s);
}
int main(int argc, char * argv[]) {
const int ms = passive_tcp(opts['s'], tcp_qlen);
if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
errexit("signal(sigchld) failed:");
while (true) {
int ss = accept_tcp(ms);
switch (fork()) {
case 0:
(void) close(ms);
echo(ss);
return EXIT_SUCCESS;
default:
(void) close(ss);
break;
}
}
return EXIT_SUCCESS;
}
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 11 req/sec, 461.5 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 253.2 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 257.2 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 170.5 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 165.8 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 166.8 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 123.4 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 123.0 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 123.6 kbytes/sec. cs17 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 124.5 kbytes/sec.
if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
errexit("signal(sigchld) failed:");
Not POSIX compliant.
signal(), use sigset()
static void * echo(void * arg) {
const int s = (int) arg;
const unsigned buffer_size = 1024*16;
char * buffer = new char[buffer_size];
int cc;
while ((cc = read(s, buffer, buffer_size)) > 0)
write(s, buffer, cc) < 0)
close(s);
delete [] buffer;
return 0;
}
#define create_pthread(_t, _a, _f, _v) \
do { const int e = pthread_create(&(_t), &(_a), \
reinterpret_cast(_f), \
reinterpret_cast(_v)); \
if (e) errexit("%d = pthread_create(%s) failed:", e, #_f); \
} while (false)
int main(int argc, char * argv[]) {
const int ms = passive_tcp(opts['s'], tcp_qlen);
pthread_t th;
pthread_attr_t ta;
(void) pthread_attr_init(&ta);
(void) pthread_attr_setdetachstate(&ta, PTHREAD_CREATE_DETACHED);
while (true)
create_pthread(th, ta, echo, accept_tcp(ms));
return EXIT_SUCCESS;
}
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 12 req/sec, 493.1 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 269.1 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 269.2 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 171.1 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 169.1 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 171.5 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 122.7 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 123.2 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 122.7 kbytes/sec. cs17 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 122.8 kbytes/sec.
const unsigned buffer_size = 1024*16;
static char buffer[buffer_size];
static int echo(int s) {
const int cc = read(s, buffer, sizeof(buffer));
write(s, buffer, cc);
return cc;
}
int main(int argc, char * argv[]) {
const int ms = passive_tcp(opts['s'], tcp_qlen);
const int nfds = getdtablesize();
fd_set rfds, afds;
FD_ZERO(&afds);
FD_SET(ms, &afds);
while (true) {
memcpy(&rfds, &afds, sizeof(rfds));
const int e =
select(nfds, &rfds, NULL, NULL, (struct timeval *) 0);
if (e < 0) errexit("select() error:");
if (FD_ISSET(ms, &rfds)) {
int s = accept_tcp(ms);
FD_SET(s, &afds);
}
for (int fd = 0; fd < nfds; fd++)
if ((fd != ms) && (FD_ISSET(fd, &rfds)))
if (!echo(fd)) {
(void) close(fd);
FD_CLR(fd, &afds);
}
}
return EXIT_SUCCESS;
}
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 12 req/sec, 518.9 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 7 req/sec, 281.9 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 6 req/sec, 260.4 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 176.6 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 172.2 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 4 req/sec, 172.1 kbytes/sec.
cs14 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 125.4 kbytes/sec. cs16 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 124.0 kbytes/sec. cs20 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 123.9 kbytes/sec. cs17 ./c -h clayton -s 1956 -b 40000 -i 300 300 reqs, 40000 size, 3 req/sec, 124.2 kbytes/sec.
if (FD_ISSET(ms, &rfds)) FD_SET(accept_tcp(ms), &afds);
This page last modified on 23 March 2001.