Chinaunix首页 | 论坛 | 博客
  • 博客访问: 36760
  • 博文数量: 18
  • 博客积分: 485
  • 博客等级: 下士
  • 技术积分: 125
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-28 11:55
文章分类
文章存档

2011年(18)

我的朋友

分类: C/C++

2011-05-11 14:42:24

看到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。

  1.     #include <string>
  2.     #include <iostream>
  3.     #include <algorithm>
  4.     #include <boost/asio.hpp>
  5.     using namespace std;
  6.     using namespace boost;
  7.     using boost::asio::ip::tcp;
  8.       
  9.     #define CHECK_ERROR_CODE(code) if (code) { cerr << code.message() << endl; return; }
  10.     class HttpClient
  11.     {
  12.         asio::io_service &io_service_;
  13.         asio::streambuf buffer_;
  14.         tcp::socket socket_;
  15.         tcp::resolver resolver_;
  16.         string domain_;
  17.       
  18.         public:
  19.         HttpClient(asio::io_service &io_service) : io_service_(io_service), socket_(io_service), resolver_(io_service)
  20.         {
  21.       
  22.         }
  23.       
  24.         void get(const string &domain)
  25.         {
  26.             resolve(domain);
  27.         }
  28.       
  29.         void resolve(const string &domain)
  30.         {
  31.             domain_ = domain;
  32.             tcp::resolver::query query(domain, "http");
  33.             resolver_.async_resolve(query,
  34.                 [this](const system::error_code &code, tcp::resolver::iterator iterator) {
  35.                     CHECK_ERROR_CODE(code);
  36.                     connect( iterator->endpoint() );
  37.                 }
  38.             );
  39.         }
  40.       
  41.       
  42.         void connect(tcp::endpoint remote_endpoint)
  43.         {
  44.             socket_.async_connect(remote_endpoint,
  45.                 [this](const system::error_code &code) {
  46.                     CHECK_ERROR_CODE(code);
  47.                     send_header();
  48.                 }
  49.             );
  50.         }
  51.       
  52.       
  53.         void send_header()
  54.         {
  55.             string request_header("GET / HTTP/1.1\r\nHost: "+domain_+"\r\nConnection: close\r\n\r\n");
  56.             async_write(socket_, asio::buffer(request_header), asio::transfer_all(),
  57.                 [this](const system::error_code &code, size_t n) {
  58.                     CHECK_ERROR_CODE(code);
  59.                     recv_any();
  60.                 }
  61.             );
  62.         }
  63.       
  64.       
  65.         void recv_any()
  66.         {
  67.             async_read(socket_, buffer_, asio::transfer_at_least(1),
  68.                 [this](const system::error_code &code, size_t n) {
  69.                     size_t size = asio::buffer_size(buffer_.data());
  70.                     if (size>0) {
  71.                         const char *data = asio::buffer_cast<const char*>(buffer_.data());
  72.                         cout.write(data, size);
  73.                         buffer_.consume(size);
  74.                     }
  75.       
  76.                     CHECK_ERROR_CODE(code);
  77.                     recv_any();
  78.                 }
  79.             );
  80.         }
  81.     };
  82.       
  83.     int main(int argc, char *argv[])
  84.     {
  85.         if (argc<2) {
  86.             cerr << "http-get domain" << endl;
  87.             return 1;
  88.         }
  89.         asio::io_service io_service;
  90.         HttpClient client(io_service);
  91.         client.get(argv[1]);
  92.       
  93.         io_service.run();
  94.         return 0;
  95.     }
另存为http-get.cc,编译并运行
  1. $ g++ -std=c++0x -lboost_system -lboost_thread http-get.cc -o http-get
  2. $ ./http-get
  3. HTTP/1.1 200 OK
  4. Date: Sun, 27 Mar 2011 20:36:51 GMT
  5. Server: BWS/1.0
  6. Content-Length: 6759
  7. Content-Type: text/html;charset=gb2312
  8. Cache-Control: private
  9. Expires: Sun, 27 Mar 2011 20:36:51 GMT
  10. Set-Cookie: BAIDUID=83C77B5AA4FFE997F526519A3612F959:FG=1; expires=Sun, 27-Mar-41 20:36:51 GMT; path=/; domain=.baidu.com
  11. P3P: CP=" OTI DSP COR IVA OUR IND COM "
  12. Connection: Close

  13. <
  14. ...
  15. ...
  16. End of file

阅读(549) | 评论(0) | 转发(0) |
0

上一篇:C++0x

下一篇:C++0x 初探

给主人留下些什么吧!~~