2019-07-28 10:31:56 +08:00
|
|
|
|
#include "stdafx.h"
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
|
|
|
|
using namespace acl;
|
|
|
|
|
|
|
|
|
|
static int __loop_count = 10;
|
|
|
|
|
static connect_manager* __conn_manager = NULL;
|
|
|
|
|
static acl_pthread_pool_t* __thr_pool = NULL;
|
|
|
|
|
static bool __unzip = false;
|
|
|
|
|
|
|
|
|
|
static void sleep_while(int n)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < n; i++)
|
|
|
|
|
{
|
|
|
|
|
putchar('.');
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
sleep(1);
|
|
|
|
|
}
|
|
|
|
|
printf("\r\n");
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
static void init(const char* addrs, int count)
|
|
|
|
|
{
|
2015-11-14 00:32:27 +08:00
|
|
|
|
int cocurrent = 100, conn_timeout = 100, rw_timeout = 200;
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳؼ<D3B3>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
__conn_manager = new http_request_manager();
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD><C8BA>ַ
|
2015-11-14 00:32:27 +08:00
|
|
|
|
__conn_manager->init(addrs, addrs, cocurrent, conn_timeout, rw_timeout);
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
|
|
|
|
printf(">>>start monitor thread\r\n");
|
|
|
|
|
|
2015-11-14 00:32:27 +08:00
|
|
|
|
int check_inter = 1, check_conn_timeout = 5;
|
2015-04-07 23:31:31 +08:00
|
|
|
|
acl::connect_monitor* monitor = new acl::connect_monitor(*__conn_manager);
|
2015-11-14 00:32:27 +08:00
|
|
|
|
(*monitor).set_check_inter(check_inter).set_conn_timeout(check_conn_timeout);
|
2015-04-07 23:31:31 +08:00
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
2015-04-07 23:31:31 +08:00
|
|
|
|
__conn_manager->start_monitor(monitor);
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int n = 10;
|
|
|
|
|
printf(">>>sleep %d seconds for monitor check\r\n", n);
|
|
|
|
|
sleep_while(n);
|
|
|
|
|
|
|
|
|
|
printf(">>>create thread pool\r\n");
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>̳߳<DFB3>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
__thr_pool = acl_thread_pool_create(count, 60);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
|
2014-11-19 00:25:21 +08:00
|
|
|
|
static void end(void)
|
|
|
|
|
{
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>̳߳<DFB3>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
acl_pthread_pool_destroy(__thr_pool);
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
int n = 10;
|
|
|
|
|
printf("\r\n>>>sleep %d seconds to stop monitor\r\n", n);
|
|
|
|
|
sleep_while(n);
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳؼ<D3B3>Ⱥ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>״̬
|
2014-11-19 00:25:21 +08:00
|
|
|
|
printf("\r\n");
|
|
|
|
|
std::vector<connect_pool*>& pools = __conn_manager->get_pools();
|
|
|
|
|
std::vector<connect_pool*>::const_iterator cit = pools.begin();
|
|
|
|
|
for (; cit != pools.end(); ++cit)
|
|
|
|
|
{
|
|
|
|
|
printf(">>>server: %s, %s\r\n",
|
|
|
|
|
(*cit)->get_addr(), (*cit)->aliving()
|
|
|
|
|
? "alive" : "dead");
|
|
|
|
|
}
|
|
|
|
|
printf("\r\n>>> STOPPING check thread now\r\n");
|
2015-04-07 23:31:31 +08:00
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// ֹͣ<CDA3><D6B9>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
2015-04-07 23:31:31 +08:00
|
|
|
|
acl::connect_monitor* monitor = __conn_manager->stop_monitor(true);
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2015-04-07 23:31:31 +08:00
|
|
|
|
delete monitor;
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
delete __conn_manager;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
static bool http_get(http_request* conn, const char* addr, int n)
|
|
|
|
|
{
|
|
|
|
|
if (0)
|
|
|
|
|
printf(">>>check addr: %s, n: %d\r\n", addr, n);
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
http_header& header = conn->request_header();
|
|
|
|
|
header.set_url("/")
|
|
|
|
|
.set_host(addr)
|
|
|
|
|
.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);
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD> HTTP <20><>Ӧͷ
|
2014-11-19 00:25:21 +08:00
|
|
|
|
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;
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
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 check_all_connections(void)
|
|
|
|
|
{
|
|
|
|
|
std::vector<connect_pool*>& pools = __conn_manager->get_pools();
|
|
|
|
|
std::vector<connect_pool*>::const_iterator cit = pools.begin();
|
|
|
|
|
for (; cit != pools.end(); ++cit)
|
|
|
|
|
printf(">>>addr: %s %s\r\n", (*cit)->get_addr(),
|
|
|
|
|
(*cit)->aliving() ? "alive" : "dead");
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
static void thread_main(void*)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < __loop_count; i++)
|
|
|
|
|
{
|
|
|
|
|
http_request_pool* pool = (http_request_pool*)
|
|
|
|
|
__conn_manager->peek();
|
|
|
|
|
if (pool == NULL)
|
|
|
|
|
{
|
|
|
|
|
printf("\r\n>>>%lu(%d): peek pool failed<<<\r\n",
|
|
|
|
|
(unsigned long) acl_pthread_self(), __LINE__);
|
|
|
|
|
check_all_connections();
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>л<EFBFBD>ȡһ<C8A1><D2BB> HTTP <20><><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
http_request* conn = (http_request*) pool->peek();
|
|
|
|
|
if (conn == NULL)
|
|
|
|
|
{
|
|
|
|
|
printf("\r\n>>>%lu: peek connect failed from %s<<<\r\n",
|
|
|
|
|
(unsigned long) acl_pthread_self(),
|
|
|
|
|
pool->get_addr());
|
|
|
|
|
check_all_connections();
|
|
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>Ҫ<EFBFBD>Ի<EFBFBD><D4BB>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
else
|
|
|
|
|
conn->reset();
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>ʼ<EFBFBD>µ<EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
if (http_get(conn, pool->get_addr(), i) == false)
|
|
|
|
|
{
|
|
|
|
|
printf("one request failed, close connection\r\n");
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ر<EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
pool->put(conn, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pool->put(conn, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0)
|
|
|
|
|
printf(">>>>thread: %lu OVER<<<<\r\n",
|
|
|
|
|
(unsigned long) acl_pthread_self());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void run(int cocurrent)
|
|
|
|
|
{
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD>̳߳<DFB3><CCB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
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_addrs [www.sina.com.cn:80;www.263.net:80;www.qq.com: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 addrs("www.sina.com.cn:80;www.263.net:80;www.qq.com:81");
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>ʼ<EFBFBD><CABC> acl <20><>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
acl::acl_cpp_init();
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
acl::log::stdout_open(true);
|
|
|
|
|
|
|
|
|
|
while ((ch = getopt(argc, argv, "hs:n:c:z")) > 0)
|
|
|
|
|
{
|
|
|
|
|
switch (ch)
|
|
|
|
|
{
|
|
|
|
|
case 'h':
|
|
|
|
|
usage(argv[0]);
|
|
|
|
|
return 0;
|
|
|
|
|
case 's':
|
|
|
|
|
addrs = 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(addrs, cocurrent);
|
|
|
|
|
run(cocurrent);
|
|
|
|
|
end();
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
printf("enter any key to exit...\r\n");
|
|
|
|
|
getchar();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|