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(port, 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(port, tcp_qlen) if signal(SIGCHLD, SIG_IGN) == SIG_ERR errexit("signal(sigchld) failed:") while true int ss = accept_tcp(ms) switch fork() case 0: close(ms) echo(ss) return EXIT_SUCCESS default: 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()
.
signal()
has unpredictable behavior.
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 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) and (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 18 February 2004.