2019-07-28 10:31:56 +08:00
|
|
|
|
// rpc_download.cpp : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨Ӧ<CCA8>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㡣
|
2014-11-19 00:25:21 +08:00
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include "acl_cpp/lib_acl.hpp"
|
|
|
|
|
|
|
|
|
|
using namespace acl;
|
|
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
CTX_T_CONTENT_LENGTH,
|
|
|
|
|
CTX_T_PARTIAL_LENGTH,
|
|
|
|
|
CTX_T_END
|
|
|
|
|
} ctx_t;
|
|
|
|
|
|
|
|
|
|
struct DOWN_CTX
|
|
|
|
|
{
|
|
|
|
|
ctx_t type;
|
|
|
|
|
int length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int __download_count = 0;
|
|
|
|
|
|
|
|
|
|
class http_down : public rpc_request
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
http_down(aio_handle& handle, const char* addr, const char* url)
|
|
|
|
|
: handle_(handle)
|
|
|
|
|
, addr_(addr)
|
|
|
|
|
, url_(url)
|
|
|
|
|
, error_(false)
|
|
|
|
|
, total_read_(0)
|
|
|
|
|
, content_length_(0)
|
|
|
|
|
{}
|
|
|
|
|
~http_down() {}
|
|
|
|
|
protected:
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
void rpc_run()
|
|
|
|
|
{
|
2019-07-28 10:31:56 +08:00
|
|
|
|
http_request req(addr_); // HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Ϣ
|
2014-11-19 00:25:21 +08:00
|
|
|
|
req.request_header().set_url(url_.c_str())
|
|
|
|
|
.set_content_type("text/html")
|
|
|
|
|
.set_host(addr_.c_str())
|
|
|
|
|
.set_method(HTTP_METHOD_GET);
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD>ʾ HTTP <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
string header;
|
|
|
|
|
req.request_header().build_request(header);
|
|
|
|
|
printf("request: %s\r\n", header.c_str());
|
|
|
|
|
|
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 (req.request(NULL, 0) == false)
|
|
|
|
|
{
|
|
|
|
|
printf("send request error\r\n");
|
|
|
|
|
error_ = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
http_client* conn = req.get_client();
|
|
|
|
|
assert(conn);
|
|
|
|
|
DOWN_CTX* ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_CONTENT_LENGTH;
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>峤<EFBFBD><E5B3A4>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
ctx->length = (int) conn->body_length();
|
|
|
|
|
content_length_ = ctx->length;
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
rpc_signal(ctx);
|
|
|
|
|
|
|
|
|
|
char buf[8192];
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
int ret = req.read_body(buf, sizeof(buf));
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
{
|
|
|
|
|
ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_END;
|
|
|
|
|
ctx->length = ret;
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
rpc_signal(ctx);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ctx = new DOWN_CTX;
|
|
|
|
|
ctx->type = CTX_T_PARTIAL_LENGTH;
|
|
|
|
|
ctx->length = ret;
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
rpc_signal(ctx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD>Ϣ
|
2014-11-19 00:25:21 +08:00
|
|
|
|
void rpc_onover()
|
|
|
|
|
{
|
|
|
|
|
printf("%s: read over now, total read: %d, content-length: %d\r\n",
|
|
|
|
|
addr_.c_str(), total_read_, content_length_);
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><> HTTP <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD>ֹͣ<CDA3>¼<EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
__download_count--;
|
|
|
|
|
if (__download_count == 0)
|
|
|
|
|
handle_.stop();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><CCA3>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>̵߳<DFB3>֪ͨ<CDA8><D6AA>Ϣ
|
2014-11-19 00:25:21 +08:00
|
|
|
|
void rpc_wakeup(void* ctx)
|
|
|
|
|
{
|
|
|
|
|
DOWN_CTX* down_ctx = (DOWN_CTX*) ctx;
|
|
|
|
|
switch (down_ctx->type)
|
|
|
|
|
{
|
|
|
|
|
case CTX_T_CONTENT_LENGTH:
|
|
|
|
|
printf("%s: content-length: %d\r\n",
|
|
|
|
|
addr_.c_str(), down_ctx->length);
|
|
|
|
|
break;
|
|
|
|
|
case CTX_T_PARTIAL_LENGTH:
|
|
|
|
|
total_read_ += down_ctx->length;
|
|
|
|
|
printf("%s: partial-length: %d, total read: %d\r\n",
|
|
|
|
|
addr_.c_str(), down_ctx->length, total_read_);
|
|
|
|
|
break;
|
|
|
|
|
case CTX_T_END:
|
|
|
|
|
printf("%s: read over\r\n", addr_.c_str());
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf("%s: ERROR\r\n", addr_.c_str());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
delete down_ctx;
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
aio_handle& handle_;
|
|
|
|
|
string addr_;
|
|
|
|
|
string url_;
|
|
|
|
|
bool error_;
|
|
|
|
|
int total_read_;
|
|
|
|
|
int content_length_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void run(void)
|
|
|
|
|
{
|
|
|
|
|
aio_handle handle;
|
2019-07-28 10:31:56 +08:00
|
|
|
|
rpc_service* service = new rpc_service(10); // <20><><EFBFBD><EFBFBD> rpc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
if (service->open(&handle) == false)
|
|
|
|
|
{
|
|
|
|
|
printf("open service error: %s\r\n", last_serror());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
|
|
|
|
|
http_down down1(handle, "www.sina.com.cn:80", "http://www.sina.com.cn/");
|
2019-07-28 10:31:56 +08:00
|
|
|
|
service->rpc_fork(&down1); // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ự<EFBFBD><E1BBB0><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
__download_count++;
|
|
|
|
|
|
|
|
|
|
http_down down2(handle, "www.hexun.com:80", "/");
|
2019-07-28 10:31:56 +08:00
|
|
|
|
service->rpc_fork(&down2); // <20><><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ự<EFBFBD><E1BBB0><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
__download_count++;
|
|
|
|
|
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20>첽<EFBFBD>¼<EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (handle.check() == false)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete service;
|
2019-07-28 10:31:56 +08:00
|
|
|
|
handle.check(); // <20><>֤<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳٹرյ<D8B1><D5B5>첽<EFBFBD><ECB2BD><EFBFBD><EFBFBD>
|
2014-11-19 00:25:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
acl_cpp_init();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
run();
|
|
|
|
|
printf("Enter any key to continue\r\n");
|
|
|
|
|
getchar();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|