mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-02 20:08:21 +08:00
d06cfbdb8d
这个样例不太严谨,没有正确添加host头域到header中,sina返回状态码必然是400。 set_url函数里面没有关于相对路径的host头域处理,可能是疏忽了?
166 lines
3.6 KiB
C++
166 lines
3.6 KiB
C++
#include "stdafx.h"
|
|
|
|
using namespace acl;
|
|
|
|
static int __loop_count = 10;
|
|
static connect_pool* __conn_pool = NULL;
|
|
static acl_pthread_pool_t* __thr_pool = NULL;
|
|
static bool __unzip = false;
|
|
|
|
// 初始化过程
|
|
static void init(const char* addr, int count)
|
|
{
|
|
// 创建 HTTP 请求连接池对象
|
|
__conn_pool = new http_request_pool(addr, count);
|
|
|
|
// 创建线程池
|
|
__thr_pool = acl_thread_pool_create(count, 60);
|
|
}
|
|
|
|
// 进程退出前清理资源
|
|
static void end(void)
|
|
{
|
|
// 销毁线程池
|
|
acl_pthread_pool_destroy(__thr_pool);
|
|
|
|
// 销毁连接池
|
|
delete __conn_pool;
|
|
}
|
|
|
|
// HTTP 请求过程,向服务器发送请求后从服务器读取响应数据
|
|
static bool http_get(http_request* conn, int n)
|
|
{
|
|
// 创建 HTTP 请求头数据
|
|
http_header& header = conn->request_header();
|
|
header.set_host("www.sina.com.cn")
|
|
.set_url("/")
|
|
.set_keep_alive(true)
|
|
.set_method(HTTP_METHOD_GET)
|
|
.accept_gzip(__unzip);
|
|
|
|
if (0)
|
|
printf("%lu--%d: begin send request\r\n",
|
|
(unsigned long) acl_pthread_self(), n);
|
|
// 发送 HTTP 请求数据同时接收 HTTP 响应头
|
|
if (conn->request(NULL, 0) == false)
|
|
{
|
|
printf("%lu--%d: send GET request error\r\n",
|
|
(unsigned long) acl_pthread_self(), n);
|
|
return false;
|
|
}
|
|
|
|
char buf[8192];
|
|
int ret, length = 0;
|
|
|
|
// 接收 HTTP 响应体数据
|
|
while (true)
|
|
{
|
|
ret = conn->read_body(buf, sizeof(buf));
|
|
if (ret == 0)
|
|
break;
|
|
else if (ret < 0)
|
|
{
|
|
printf("%lu--%d: error, length: %d\r\n",
|
|
(unsigned long) acl_pthread_self(), n, length);
|
|
return false;
|
|
}
|
|
length += ret;
|
|
if (0)
|
|
printf("%lu--%d: read length: %d, %d\r\n",
|
|
(unsigned long) acl_pthread_self(), n, length, ret);
|
|
}
|
|
if (0)
|
|
printf("%lu--%d: read body over, length: %d\r\n",
|
|
(unsigned long) acl_pthread_self(), n, length);
|
|
return true;
|
|
}
|
|
|
|
// 线程处理过程
|
|
static void thread_main(void*)
|
|
{
|
|
for (int i = 0; i < __loop_count; i++)
|
|
{
|
|
// 从连接池中获取一个 HTTP 连接
|
|
http_request* conn = (http_request*) __conn_pool->peek();
|
|
if (conn == NULL)
|
|
{
|
|
printf("peek connect failed\r\n");
|
|
break;
|
|
}
|
|
|
|
// 需要对获得的连接重置状态,以清除上次请求过程的临时数据
|
|
else
|
|
conn->reset();
|
|
// 开始新的 HTTP 请求过程
|
|
if (http_get(conn, i) == false)
|
|
{
|
|
printf("one request failed, close connection\r\n");
|
|
// 错误连接需要关闭
|
|
__conn_pool->put(conn, false);
|
|
}
|
|
else
|
|
__conn_pool->put(conn, true);
|
|
}
|
|
}
|
|
|
|
static void run(int cocurrent)
|
|
{
|
|
// 向线程池中添加任务
|
|
for (int i = 0; i < cocurrent; i++)
|
|
acl_pthread_pool_add(__thr_pool, thread_main, NULL);
|
|
}
|
|
|
|
static void usage(const char* procname)
|
|
{
|
|
printf("usage: %s -h [help]\r\n"
|
|
" -s http_server_addr [www.sina.com.cn:80]\r\n"
|
|
" -z [unzip response body, default: false]\r\n"
|
|
" -c cocurrent [default: 10]\r\n"
|
|
" -n loop_count[default: 10]\r\n", procname);
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
int ch, cocurrent = 10;
|
|
string addr("www.sina.com.cn:80");
|
|
|
|
// 初始化 acl 库
|
|
acl::acl_cpp_init();
|
|
|
|
while ((ch = getopt(argc, argv, "hs:n:c:z")) > 0)
|
|
{
|
|
switch (ch)
|
|
{
|
|
case 'h':
|
|
usage(argv[0]);
|
|
return 0;
|
|
case 's':
|
|
addr = optarg;
|
|
break;
|
|
case 'c':
|
|
cocurrent = atoi(optarg);
|
|
break;
|
|
case 'n':
|
|
__loop_count = atoi(optarg);
|
|
break;
|
|
case 'z':
|
|
__unzip = true;
|
|
break;
|
|
default:
|
|
usage(argv[0]);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
init(addr, cocurrent);
|
|
run(cocurrent);
|
|
end();
|
|
|
|
#ifdef WIN32
|
|
printf("enter any key to exit...\r\n");
|
|
getchar();
|
|
#endif
|
|
|
|
return 0;
|
|
}
|