/* Copyright (C) 2007 Eric Dumazet This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int fd __attribute__((aligned(64))); int port = 9999; unsigned long nb_acc __attribute__((aligned(64))); unsigned long nb_conn1 __attribute__((aligned(64))); unsigned long nb_conn2 __attribute__((aligned(64))); unsigned long nb_conn3 __attribute__((aligned(64))); int limit = 10000/3; void *do_accept(void *arg) { int s; struct sockaddr_in sa; socklen_t addrlen ; int flags; char buffer[1024]; while (1) { addrlen = sizeof(sa); s = accept(fd, (struct sockaddr *)&sa, &addrlen); if (s == -1) continue; flags = 0; recv(s, buffer, 1024, 0); send(s, "Answer\r\n", 8, 0); close(s); nb_acc++; } } void *do_conn(void *arg) { int i; int on = 1; struct sockaddr_in sa; unsigned long *cpt = (unsigned long *)arg; for (i = 0 ; i < limit ; i++) { int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int res; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, 4); memset(&sa, 0, sizeof(sa)); sa.sin_addr.s_addr = htonl(0x7f000001); sa.sin_port = htons(port); sa.sin_family = AF_INET; res = connect(s, (struct sockaddr *)&sa, sizeof(sa)); if (res == 0) { char buffer[1024]; send(s, "question\r\n", 10, 0); recv(s, buffer, sizeof(buffer), 0); (*cpt)++; } else { static int errcnt = 0; if (errcnt++ < 10) printf("connect error %d\n", errno); } close(s); } } int main(int argc, char *argv[]) { int on = 1; struct sockaddr_in sa; pthread_t tid, tid1, tid2, tid3; int i; void *res; while ((i = getopt(argc, argv, "Vn:")) != EOF) { if (i == 'n') limit = atoi(optarg) / 3; } fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, 4); memset(&sa, 0, sizeof(sa)); sa.sin_port = htons(port); sa.sin_family = AF_INET; if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { perror("bind"); return 1; } listen(fd, 30000); pthread_create(&tid, NULL, do_accept, NULL); pthread_create(&tid1, NULL, do_conn, &nb_conn1); pthread_create(&tid2, NULL, do_conn, &nb_conn2); pthread_create(&tid3, NULL, do_conn, &nb_conn3); pthread_join(tid1, &res); pthread_join(tid2, &res); pthread_join(tid3, &res); printf("nb_conn=%lu nb_accp=%lu\n", nb_conn1 + nb_conn2 + nb_conn3, nb_acc); return 0; }