/** * This code creates N threads. Each threads does one GET to an address. The * GET, the address and the number of threads are passed as argument. An "\r\n" * is appended to the GET string. */ /* headers *//*{{{*/ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <pthread.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netdb.h>/*}}}*/ /* declarations and prototypes */ /*{{{*/ #define pexit(s) ({perror(s); exit(exit_failure);}) static struct cstats { int socket_errors; int send_errors; int recv_errors; int connect_errors; int avg_respt; /* average response time */ pthread_mutex_t mutex; } cstats; struct sockaddr_in addr; #define buflen 1024 static char buf[buflen]; static int buf_len; void *get_get_thread(void *);/*}}}*/ int main(int argc, char **argv) { /* main declarations *//*{{{*/ int i; int fail = 0; int ngets; int addr_len; int error; struct hostent *host; pthread_t *threadv; pthread_attr_t attr;/*}}}*/ /* error checking *//*{{{*/ if (argc <= 4) { printf("usage: %s address port number_of_gets get_string\n", argv[0]); exit(exit_failure); } ngets = atoi(argv[3]); if (ngets <= 0) { printf("number_of_gets\n"); errno = einval; exit(exit_failure); } /*}}}*/ bzero(&cstats, sizeof(struct cstats)); /* pthread initialization *//*{{{*/ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, pthread_create_joinable); pthread_mutex_init(&cstats.mutex, null); threadv = malloc(sizeof(pthread_t) * ngets); if (!threadv) pexit("malloc");/*}}}*/ /* address initialization *//*{{{*/ strncpy(buf, argv[4], buflen); strncat(buf, "\r\n", buflen); host = gethostbyname(argv[1]); if (!host) pexit("gethostbyname"); memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], sizeof(struct sockaddr_in)); addr.sin_family = pf_inet; addr.sin_port = htons(atoi(argv[2])); /*}}}*/ /* creating threads *//*{{{*/ for (i = 0; i < ngets; i++) { error = pthread_create(&threadv[i], &attr, get_get_thread, null); if (error) fail++; }/*}}}*/ printf("%d thread created. Running...\n", ngets - fail); /* joing threads *//*{{{*/ for (i = 0; i < ngets; i++) { error = pthread_join(threadv[i], null); if (error) perror("pthread_join"); }/*}}}*/ /* output *//*{{{*/ printf("errors:\n" " socket() errors: %d\n" " connect() errors: %d\n" " send() errors: %d\n" " recv() errors: %d\n", cstats.socket_errors, cstats.connect_errors, cstats.send_errors, cstats.recv_errors);/*}}}*/ return 0; } void *get_get_thread(void *dummy)/*{{{*/ { int error; int nbytes; int sock; #define RBUF_LEN 1024 char rbuf[RBUF_LEN]; sock = socket(PF_INET, SOCK_STREAM, 0);/*{{{*/ if (sock < 0) { pthread_mutex_lock(&cstats.mutex); cstats.socket_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ error = connect(sock, (struct sockaddr *)&addr, sizeof addr);/*{{{*/ if (error) { pthread_mutex_lock(&cstats.mutex); cstats.connect_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ nbytes = send(sock, buf, strlen(buf) , 0);/*{{{*/ if (nbytes == -1) /* error */ { pthread_mutex_lock(&cstats.mutex); cstats.send_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ nbytes = recv(sock, rbuf, RBUF_LEN, 0);/*{{{*/ if (nbytes == -1) { pthread_mutex_lock(&cstats.mutex); cstats.recv_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ close(sock); return (void *)0; }/*}}}*/ /* vim: set fdm=marker: tw=80 : */
quinta-feira, 5 de janeiro de 2012
TCP Flooder with pthreads
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário