看到C++0x的lambda特性,随想到boost::asio,于是拿来练练手,的确很方便。但总有***的感觉。
以下代码的编译环境还是满苛刻的。
本人的编译环境为gcc 4.5.2 + boost 1.46。C++0x lambda则需要gcc 4.5以上版本
程序功能
命令:http-get 域名
功能:输出域名的首页,接收所有数据。因为是所有数据。所以有的数据会包含Chunked信息。
代码比较简单,都是最基本的应用,所以没啥注释。由于asio的handler全使用了lambda,代码整洁了许多,没有了长长的bind。
- #include <string>
-
#include <iostream>
-
#include <algorithm>
-
#include <boost/asio.hpp>
-
using namespace std;
-
using namespace boost;
-
using boost::asio::ip::tcp;
-
-
#define CHECK_ERROR_CODE(code) if (code) { cerr << code.message() << endl; return; }
-
class HttpClient
-
{
-
asio::io_service &io_service_;
-
asio::streambuf buffer_;
-
tcp::socket socket_;
-
tcp::resolver resolver_;
-
string domain_;
-
-
public:
-
HttpClient(asio::io_service &io_service) : io_service_(io_service), socket_(io_service), resolver_(io_service)
-
{
-
-
}
-
-
void get(const string &domain)
-
{
-
resolve(domain);
-
}
-
-
void resolve(const string &domain)
-
{
-
domain_ = domain;
-
tcp::resolver::query query(domain, "http");
-
resolver_.async_resolve(query,
-
[this](const system::error_code &code, tcp::resolver::iterator iterator) {
-
CHECK_ERROR_CODE(code);
-
connect( iterator->endpoint() );
-
}
-
);
-
}
-
-
-
void connect(tcp::endpoint remote_endpoint)
-
{
-
socket_.async_connect(remote_endpoint,
-
[this](const system::error_code &code) {
-
CHECK_ERROR_CODE(code);
-
send_header();
-
}
-
);
-
}
-
-
-
void send_header()
-
{
-
string request_header("GET / HTTP/1.1\r\nHost: "+domain_+"\r\nConnection: close\r\n\r\n");
-
async_write(socket_, asio::buffer(request_header), asio::transfer_all(),
-
[this](const system::error_code &code, size_t n) {
-
CHECK_ERROR_CODE(code);
-
recv_any();
-
}
-
);
-
}
-
-
-
void recv_any()
-
{
-
async_read(socket_, buffer_, asio::transfer_at_least(1),
-
[this](const system::error_code &code, size_t n) {
-
size_t size = asio::buffer_size(buffer_.data());
-
if (size>0) {
-
const char *data = asio::buffer_cast<const char*>(buffer_.data());
-
cout.write(data, size);
-
buffer_.consume(size);
-
}
-
-
CHECK_ERROR_CODE(code);
-
recv_any();
-
}
-
);
-
}
-
};
-
-
int main(int argc, char *argv[])
-
{
-
if (argc<2) {
-
cerr << "http-get domain" << endl;
-
return 1;
-
}
-
asio::io_service io_service;
-
HttpClient client(io_service);
-
client.get(argv[1]);
-
-
io_service.run();
-
return 0;
-
}
另存为http-get.cc,编译并运行
- $ g++ -std=c++0x -lboost_system -lboost_thread http-get.cc -o http-get
-
$ ./http-get
-
HTTP/1.1 200 OK
-
Date: Sun, 27 Mar 2011 20:36:51 GMT
-
Server: BWS/1.0
-
Content-Length: 6759
-
Content-Type: text/html;charset=gb2312
-
Cache-Control: private
-
Expires: Sun, 27 Mar 2011 20:36:51 GMT
-
Set-Cookie: BAIDUID=83C77B5AA4FFE997F526519A3612F959:FG=1; expires=Sun, 27-Mar-41 20:36:51 GMT; path=/; domain=.baidu.com
-
P3P: CP=" OTI DSP COR IVA OUR IND COM "
-
Connection: Close
-
-
<
-
...
-
...
-
-
End of file
阅读(549) | 评论(0) | 转发(0) |