一个简单的HTTP并发测试程序
2011-09-21 14:16
489 查看
#include <stdio.h> #include <stdlib.h> #include <curl/curl.h> #include <string.h> #include <pthread.h> #include <unistd.h> #define MAX_THREAD 500 static unsigned long long run_time = 0; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct HttpStatistics //计时 { unsigned long long requestTime; unsigned long long responseTime; }; struct HttpGetParam //参数 { char *url; struct HttpStatistics httpStatistics; }; unsigned long long GetCurrentNanoseconds()//当前时间 { struct timespec tvTime; clock_gettime(CLOCK_REALTIME, &tvTime); return (unsigned long long)tvTime.tv_sec * 1000000000ULL + (unsigned long long)tvTime.tv_nsec; } static size_t write_data(void *ptr, size_t size, size_t nmemb, void *param) { return size * nmemb; } static size_t head_data(void *ptr, size_t size, size_t nmemb, void *param) { struct HttpGetParam *phttpGetParam = (struct HttpGetParam *)param; unsigned long long currentTime = 0; unsigned long long usedTime = 0; if ( phttpGetParam->httpStatistics.responseTime == 0)//只记录第一次收到报文时候的内容 { currentTime = GetCurrentNanoseconds(); phttpGetParam->httpStatistics.responseTime = currentTime; usedTime = currentTime - phttpGetParam->httpStatistics.requestTime; //printf("Time is:%llu\n", usedTime/1000000); //printf("%s\n", (char*)ptr); pthread_mutex_lock(&mutex); run_time++; pthread_mutex_unlock(&mutex); } return size * nmemb; } //每个线程的处理 void * http_get(void *param) { struct HttpGetParam *phttpGetParam = (struct HttpGetParam *)param; CURL *curl;//定义CURL类型的指针 CURLcode res; //定义CURLcode类型的变量 //pthread_detach(pthread_self()); curl = curl_easy_init();//初始化一个CURL类型的指针 //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);//这里打开libcurl打印所有调试信息 //curl_easy_setopt(curl, CURLOPT_WRITEDATA, phttpGetParam); curl_easy_setopt(curl, CURLOPT_HEADERDATA, phttpGetParam); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); //加上这一句就不会把HTTP Body打出来了。。。 //curl_easy_setopt(curl, CURLOPT_NOBODY, 1);//CURLOPT_NOBODY只下报文头,不包括数据.但是这里默认是head命令,这里注释掉,则是GET命令 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, head_data); //设置curl选项. 其中CURLOPT_URL是让用户指定url. argv[1]中存放的命令行传进来的网址 curl_easy_setopt(curl, CURLOPT_URL, phttpGetParam->url); while( 1 ) { phttpGetParam->httpStatistics.requestTime = GetCurrentNanoseconds(); phttpGetParam->httpStatistics.responseTime = 0; //调用curl_easy_perform 执行我们的设置.并进行相关的操作. 在这里只在屏幕上显示出来. res = curl_easy_perform(curl);//这里可以用循环实现每个线程内部多次处理 //printf("res=%d\n", res); } //清除curl操作. curl_easy_cleanup(curl); return NULL; } int main(int argc, char *argv[]) { CURLcode res; //定义CURLcode类型的变量 pthread_t threads[MAX_THREAD];//PID int i, ret; struct HttpGetParam httpGetParams[MAX_THREAD]; pthread_attr_t thread_attr; size_t stack_size; if (argc !=2) { printf("Usage : %s <url>;\n", argv[0]); exit(1); } res = curl_global_init(CURL_GLOBAL_ALL); if (res != CURLE_OK) { printf( "Failed to global init default [%d]\n", res ); return -1; } memset(threads, 0, sizeof(threads)); memset(httpGetParams, 0, sizeof(httpGetParams)); for ( i = 0; i < MAX_THREAD; i++) { httpGetParams[i].url = argv[1]; } printf("PTHREAD_STACK_MIN=%d\n", PTHREAD_STACK_MIN); pthread_attr_init(&thread_attr); pthread_attr_getstacksize(&thread_attr, &stack_size); printf("Default stack size is %u; minimum is %u\n", stack_size, PTHREAD_STACK_MIN); pthread_attr_setstacksize(&thread_attr, 1024 * 1024); //设置线程栈大小,这里设置成了1M,这个可能需要根据情况调,最小不能小于PTHREAD_STACK_MIN,如果太小有可能出现栈溢出 pthread_attr_getstacksize(&thread_attr, &stack_size); printf("New stack size is %u; minimum is %u\n", stack_size, PTHREAD_STACK_MIN); for ( i = 0; i < MAX_THREAD; i++) { //创建线程,threads线程ID //ret = pthread_create(&threads[i], NULL, http_get, (void *)&httpGetParams[i]); ret = pthread_create(&threads[i], &thread_attr, http_get, (void *)&httpGetParams[i]); if (0 != ret) { perror("pthread_create failed!!! The reason is:"); } if ( (i + 1) % 5 == 0) { sleep(10); printf("Thread num:%d,\tAVG request per second:%llu,\tAVG response time:%f\n", i + 1, run_time/10, 10.0/run_time); pthread_mutex_lock(&mutex); run_time = 0; pthread_mutex_unlock(&mutex); } } pthread_attr_destroy(&thread_attr); //sleep(30); //等待线程退出 for ( i = 0; i < MAX_THREAD; i++) { //判断pthread_t是否有效,解决了段错误问题。 if (threads[i] != 0) { pthread_cancel(threads[i]); pthread_join(threads[i], NULL); } } return 0; }
相关文章推荐
- 测试自动化 2011/06/11 - 1 一个最简单的GMock测试程序HelloGMock
- 一个简单的AVR测试程序
- 简单java程序测试并发数
- 一个简单的字符设备驱动程序和测试程序
- C语言实现的一个简单的HTTP程序
- 使用J2SE开发一个测试Xfire的webservice的简单程序
- 一个简单精确的asp速度测试程序
- C语言实现的一个简单的HTTP程序
- 实战 HTTP 处理程序(HTTP Handler) (1) -- 创建一个最简单的 HTTP Handler
- C语言实现的一个简单的HTTP程序
- [置顶] C语言实现的一个简单的HTTP程序(转)
- 微信小程序,学习笔记(二)样式(WXSS)及一个简单的小测试用例
- 一个简单的GNU assert用法测试程序
- C语言实现的一个简单的HTTP程序
- 一个简单的使用wininet的http/ftp文件下载程序
- 安装Thrift并写一个简单的测试程序
- 一个简单的并发程序
- 简单接口测试(http/https),方法已经封装,也写了一个窗口测试工具
- C语言实现的一个简单的HTTP程序
- 一个Nodejs的简单计算测试程序