Created
October 4, 2009 15:59
-
-
Save rsms/201450 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HTTP client for testing high connection concurrency | |
// Authors: Richard Jones and Rasmus Andersson | |
// Released in the public domain. No restrictions, no support. | |
#include <sys/types.h> | |
#include <sys/time.h> | |
#include <sys/queue.h> | |
#include <stdlib.h> | |
#include <err.h> | |
#include <event.h> | |
#include <evhttp.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <time.h> | |
#include <pthread.h> | |
#define BUFSIZE 4096 | |
#define SLEEP_MS 10 | |
// options | |
int num_conns = 100; | |
// state | |
int bytes_recvd = 0; | |
int chunks_recvd = 0; | |
int closed = 0; | |
int connected = 0; | |
int max_concurrency = 0; | |
int responses_completed_ok = 0; | |
// misc | |
char buf[BUFSIZE]; | |
// called per chunk received | |
void chunkcb(struct evhttp_request * req, void * arg) { | |
int s = evbuffer_remove( req->input_buffer, &buf, BUFSIZE ); | |
//printf("Read %d bytes: %s\n", s, &buf); | |
bytes_recvd += s; | |
chunks_recvd++; | |
} | |
// gets called when request completes | |
void reqcb(struct evhttp_request * req, void * arg) { | |
int s = evbuffer_remove( req->input_buffer, &buf, BUFSIZE ); | |
bytes_recvd += s; | |
chunks_recvd++; | |
if (connected-closed > max_concurrency) | |
max_concurrency = connected-closed; | |
responses_completed_ok++; | |
closed++; | |
} | |
int main(int argc, char * const *argv) { | |
event_init(); | |
struct evhttp_connection *evhttp_connection; | |
struct evhttp_request *evhttp_request; | |
//char addr[16]; | |
const char *remote_addr = "217.213.5.37"; | |
int remote_port = 8088; | |
const char *uri = "/msgq/listen?channel=pb"; | |
if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { | |
fprintf(stderr, "%s [connections[ address[ port[ uri]]]]\n", argv[0]); | |
return 1; | |
} | |
if (argc > 1) num_conns = atoi(argv[1]); | |
if (argc > 2) remote_addr = argv[2]; | |
if (argc > 3) remote_port = atoi(argv[3]); | |
if (argc > 4) uri = argv[4]; | |
if (num_conns > 65536) { | |
// see http://www.mail-archive.com/[email protected]/msg01302.html | |
// evhttp_connection_set_local_address can be used to send from different | |
// local addresses. | |
fprintf(stderr, "%s: connection count too high (>65536)\n", argv[0]); | |
exit(1); | |
} | |
printf("Making %d connections to http://%s:%d%s\n", num_conns, remote_addr, remote_port, uri); | |
int i; | |
for (i=1;i<=num_conns;i++) { | |
evhttp_connection = evhttp_connection_new(remote_addr, remote_port); | |
evhttp_set_timeout((struct evhttp *)evhttp_connection, 864000); // 10 day timeout | |
evhttp_request = evhttp_request_new(reqcb, NULL); | |
evhttp_request->chunk_cb = chunkcb; | |
evhttp_add_header(evhttp_request->output_headers, "Host", "hunch.se"); | |
evhttp_add_header(evhttp_request->output_headers, "Connection", "close"); | |
evhttp_make_request(evhttp_connection, evhttp_request, EVHTTP_REQ_GET, uri); | |
connected++; | |
if ( i % 100 == 0) | |
printf("%d requests sent (%d connected)\n", i, connected-closed); | |
evhttp_connection_set_timeout(evhttp_request->evcon, 864000); | |
event_loop( EVLOOP_NONBLOCK ); | |
usleep(SLEEP_MS*1000); | |
} | |
printf("All %d requests sent (%d connected).\n", num_conns, connected); | |
event_dispatch(); | |
printf("All connections are closed.\n"); | |
printf("connections: %d\tBytes: %d\tChunks: %d\tClosed: %d\n", num_conns, bytes_recvd, chunks_recvd, closed); | |
printf("Completed: %d\tFailed: %d\n", responses_completed_ok, num_conns-chunks_recvd); | |
printf("Max concurrency: %d\n", max_concurrency); | |
return 0; | |
} | |
// gcc -o floodtest -levent -I/opt/local/include -L/opt/local/lib floodtest.c |
// on Mac OS X 10.8.2
// sudo port install libevent
// export CC=/usr/bin/gcc; gcc -o c10k-test-client -l event -I /opt/local/include/ -L /opt/local/lib/ c10k-test-client.c
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
// on mac osx Lion upgrade
// brew install libevent
// export CC=/usr/bin/gcc; gcc -o c10k-test-client -levent -I/usr/local/Cellar/libevent/ -L/usr/local/Cellar/libevent/ c10k-test-client.c