#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static char doc[] = ""; static char args_doc[] = ""; static struct argp_option options[] = { {"server", 's', "host", 0, "server address"}, {"port", 'p', "int", 0, "port to connect"}, {"connections", 'c', "int", 0, "how many connections to open"}, {0}, }; struct cl_args { unsigned short port, connections; uint32_t server; }; struct cl_args cla = { .port=5555, .connections=2500, }; static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct cl_args *cla = state->input; switch (key) { case 's': { struct hostent *hostinfo =gethostbyname(arg); if (!hostinfo) { fprintf(stderr, "unknown host %s\n", arg); return -1; } cla->server=ntohl(((struct in_addr*)hostinfo->h_addr)->s_addr); break; } case 'p': { int port = atoi(arg); if (port <=0 || port > 65535) { fprintf(stderr, "invalid port: %d\n", cla->port); return -1; } cla->port=port; break; } case 'c': { cla->connections=atoi(arg); break; } case ARGP_KEY_ARG: break; default: return ARGP_ERR_UNKNOWN; } return 0; } static struct argp argp = { options, parse_opt, args_doc, doc }; static inline int is_client(void) { if (cla.server != INADDR_ANY) return 1; return 0; } #define FAIL(x) \ do { \ if (x) { \ fprintf(stderr, "%s:%d: error: %s\n", __func__, __LINE__, \ strerror(errno)); \ exit(1); \ } \ } while (0) static void run_client(void) { int i, socks[cla.connections]; struct sockaddr_in name = { .sin_port = htons (cla.port), .sin_addr = { htonl(cla.server) }, .sin_family = AF_INET }; for(i=0; i < cla.connections; i++) { FAIL((socks[i] = socket(PF_INET, SOCK_STREAM, 0)) < 0); FAIL(connect(socks[i], (struct sockaddr*)&name, sizeof(name)) < 0); } /* wait server to close */ sleep(1); for(i=0; i < cla.connections; i++) close(socks[i]); } static void run_server(int lsock) { int i, socks[cla.connections]; for(i = 0; i < cla.connections; i++) FAIL((socks[i] = accept(lsock, NULL, NULL)) < 0); for(i = 0; i < cla.connections; i++) close(socks[i]); sleep(1); } int main(int argc, char **argv) { int lsock; if (argp_parse(&argp, argc, argv, 0, 0, &cla) < 0) return -1; FAIL(system("echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse") != 0); setpriority(PRIO_PROCESS, getpid(), -20); while (1) { static int count; if (is_client()) run_client(); else { if (!count) { struct sockaddr_in name = { .sin_port = htons (cla.port), .sin_family = AF_INET }; FAIL((lsock = socket(PF_INET, SOCK_STREAM, 0)) < 0); FAIL(bind(lsock, (struct sockaddr *) &name, sizeof (name)) < 0); FAIL(listen(lsock, cla.connections) < 0); } run_server(lsock); } printf("iteration %d\n", ++count); } return 0; }