acl/lib_acl_cpp/samples/rpc_download/rpc_download.cpp

187 lines
3.8 KiB
C++
Raw Normal View History

// 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:
// <20><><EFBFBD>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2014-11-19 00:25:21 +08:00
void rpc_run()
{
http_request req(addr_); // HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2014-11-19 00:25:21 +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);
// <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());
// <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;
}
// <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;
// <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;
// ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD>
2014-11-19 00:25:21 +08:00
rpc_signal(ctx);
char buf[8192];
while (true)
{
// <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;
// ֪ͨ<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;
// ֪ͨ<CDA8><D6AA><EFBFBD>߳<EFBFBD>
2014-11-19 00:25:21 +08:00
rpc_signal(ctx);
}
}
// <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_);
// <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();
}
// <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;
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
// <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;
}
// <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/");
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", "/");
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++;
// <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;
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;
}