天天看点

boost asio 简单示例

客户端:

  1. #include <iostream>
  2. #include <boost/asio.hpp>
  3. #include <boost/bind.hpp>
  4. #include <boost/shared_ptr.hpp>
  5. #include <boost/enable_shared_from_this.hpp>
  6. using boost::asio::ip::tcp;
  7. using boost::asio::ip::address;
  8. class session: public boost::enable_shared_from_this<session> {
  9. public:
  10. (boost::asio::io_service &io_service, tcp::endpoint &endpoint)
  11. : io_service_(io_service), socket_(io_service), endpoint_(endpoint)
  12. {
  13. }
  14. void start() {
  15. .async_connect(endpoint_,
  16. ::bind(&session::handle_connect,
  17. (),
  18. ::asio::placeholders::error));
  19. }
  20. private:
  21. void handle_connect(const boost::system::error_code &error) {
  22. if (error) {
  23. if (error.value() != boost::system::errc::operation_canceled) {
  24. std::cerr << boost::system::system_error(error).what() << std::endl;
  25. }
  26. .close();
  27. return;
  28. }
  29. static tcp::no_delay option(true);
  30. .set_option(option);
  31. strcpy(buf, "Hello World!\n");
  32. ::asio::async_write(socket_,
  33. ::asio::buffer(buf, strlen(buf)),
  34. ::bind(&session::handle_write,
  35. (),
  36. ::asio::placeholders::error,
  37. ::asio::placeholders::bytes_transferred));
  38. }
  39. void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {
  40. memset(buf, sizeof(buf), 0);
  41. ::asio::async_read_until(socket_,
  42. ,
  43. "\n",
  44. ::bind(&session::handle_read,
  45. (),
  46. ::asio::placeholders::error,
  47. ::asio::placeholders::bytes_transferred));
  48. }
  49. void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
  50. std::cout << buf << std::endl;
  51. }
  52. private:
  53. ::asio::io_service &io_service_;
  54. ::socket socket_;
  55. ::endpoint &endpoint_;
  56. char buf[1024];
  57. ::asio::streambuf sbuf;
  58. };
  59. typedef boost::shared_ptr<session> session_ptr;
  60. int main(int argc, char* argv[])
  61. {
  62. ::asio::io_service io_service;
  63. ::endpoint endpoint(address::from_string("192.168.1.1"), 10028);
  64. (new session(io_service, endpoint));
  65. ->start();
  66. .run();
  67. return 0;
  68. }

服务器:

  1. #include <string.h>
  2. #include <boost/asio.hpp>
  3. #include <boost/bind.hpp>
  4. #include <boost/shared_ptr.hpp>
  5. #include <boost/enable_shared_from_this.hpp>
  6. using boost::asio::ip::tcp;
  7. using boost::asio::ip::address;
  8. class session: public boost::enable_shared_from_this<session> {
  9. public:
  10. (boost::asio::io_service &io_service): socket_(io_service)
  11. {
  12. }
  13. void start() {
  14. static tcp::no_delay option(true);
  15. .set_option(option);
  16. ::asio::async_read_until(socket_,
  17. ,
  18. "\n",
  19. ::bind(&session::handle_read,
  20. (),
  21. ::asio::placeholders::error,
  22. ::asio::placeholders::bytes_transferred));
  23. }
  24. ::socket &socket() {
  25. return socket_;
  26. }
  27. private:
  28. void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {
  29. ::asio::async_read_until(socket_,
  30. ,
  31. "\n",
  32. ::bind(&session::handle_read,
  33. (),
  34. ::asio::placeholders::error,
  35. ::asio::placeholders::bytes_transferred));
  36. }
  37. void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
  38. ::asio::async_write(socket_,
  39. ,
  40. ::bind(&session::handle_write,
  41. (),
  42. ::asio::placeholders::error,
  43. ::asio::placeholders::bytes_transferred));
  44. }
  45. private:
  46. ::socket socket_;
  47. ::asio::streambuf sbuf_;
  48. };
  49. typedef boost::shared_ptr<session> session_ptr;
  50. class server {
  51. public:
  52. (boost::asio::io_service &io_service, tcp::endpoint &endpoint)
  53. : io_service_(io_service), acceptor_(io_service, endpoint)
  54. {
  55. (new session(io_service_));
  56. .async_accept(new_session->socket(),
  57. ::bind(&server::handle_accept,
  58. this,
  59. ,
  60. ::asio::placeholders::error));
  61. }
  62. void handle_accept(session_ptr new_session, const boost::system::error_code& error) {
  63. if (error) {
  64. return;
  65. }
  66. ->start();
  67. .reset(new session(io_service_));
  68. .async_accept(new_session->socket(),
  69. ::bind(&server::handle_accept,
  70. this,
  71. ,
  72. ::asio::placeholders::error));
  73. }
  74. void run() {
  75. .run();
  76. }
  77. private:
  78. ::asio::io_service &io_service_;
  79. ::acceptor acceptor_;
  80. };
  81. int main(int argc, char* argv[])
  82. {
  83. ::asio::io_service io_service;
  84. ::endpoint endpoint(address::from_string("192.168.1.1"), 10028);
  85. (io_service, endpoint);
  86. .run();
  87. return 0;
  88. }

编译:

g++ -Wall -o client client.cpp -lboost_system

g++ -Wall -o server server.cpp -lboost_system

这里需要注意的是: async_write, async_read, async_read_until 都是需要达到特定条件才会调用回调函数,

在调用回调函数之前, 不能再次调用, 否则接收到的数据很可能是乱的. 所以, 在实际代码当中, 会有一个写缓冲队列, 当需要write的时, 先放到队列中, 如果队列个数为1, 则调用async_write, 否则等待函数回调, 当函数回调时将首个元素从队列中移除, 然后接着发送下一个, 直到队列为空.