美文网首页
boost_asio学习第3课 helloworld 服务端

boost_asio学习第3课 helloworld 服务端

作者: Mattle | 来源:发表于2017-12-14 14:33 被阅读0次

有关上篇提到的 service_registry 是什么,会在以后的文章中详细讨论。今天让我们先看一个简单的例子 —— helloworld 服务端:
废话不多,先贴代码,一步一步理解含义:
main.h:

#ifndef __MAIN__H__H__
#define __MAIN__H__H__
#include <boost\asio.hpp>

void log(const char* message);
#endif // !__MAIN__H__H__

main.cpp:

#include "main.h"

void log (const char* message) {
    std::fprintf(stdout, "%s\n", message);
}

int main() 
{
    unsigned short port = 9999; // 端口号
    boost::asio::io_service io_service; // 声明并初始化一个io_service
    boost::asio::ip::tcp protocol = boost::asio::ip::tcp::v4(); // ipv4 协议
    boost::asio::ip::tcp::endpoint endpoint(protocol, 9999); // 端点 两台计算机的连接点 
    boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint); // accept()
    log("Service Start !");
    while (true) {
        boost::asio::ip::tcp::socket socket(io_service);
        acceptor.accept(socket);
        log("Client Connected !");
        boost::system::error_code error;
        socket.write_some(boost::asio::buffer("Hello World"), error);
    }
    return 0;
}

这么几句,一个简单的服务器就写好了, 通过这个简单的例子,让我们来看看asio都为我们做了哪些事儿!

boost::asio::io_service io_service; // 声明并初始化一个io_service

初始化一个 io_service 实例,这是 asio 框架的核心。有关 io_service 的说明。我在前两篇文章中略有提及,不明白的可以去看一下。浅尝辄止就好。

boost::asio::ip::tcp protocol = boost::asio::ip::tcp::v4(); // ipv4 协议

boost::asio::ip::tcp 是个模板特化类 ——上源码

namespace boost {
namespace asio {
namespace ip {
class tcp
{
public:
  /// The type of a TCP endpoint.
  typedef basic_endpoint<tcp> endpoint;

  /// Construct to represent the IPv4 TCP protocol.
  static tcp v4()
  {
    return tcp(BOOST_ASIO_OS_DEF(AF_INET));
  }

  /// Construct to represent the IPv6 TCP protocol.
  static tcp v6()
  {
    return tcp(BOOST_ASIO_OS_DEF(AF_INET6));
  }

  /// Obtain an identifier for the type of the protocol.
  int type() const
  {
    return BOOST_ASIO_OS_DEF(SOCK_STREAM);
  }

  /// Obtain an identifier for the protocol.
  int protocol() const
  {
    return BOOST_ASIO_OS_DEF(IPPROTO_TCP);
  }

  /// Obtain an identifier for the protocol family.
  int family() const
  {
    return family_;
  }

  /// The TCP socket type.
  typedef basic_stream_socket<tcp> socket;

  /// The TCP acceptor type.
  typedef basic_socket_acceptor<tcp> acceptor;

  /// The TCP resolver type.
  typedef basic_resolver<tcp> resolver;

#if !defined(BOOST_ASIO_NO_IOSTREAM)
  /// The TCP iostream type.
  typedef basic_socket_iostream<tcp> iostream;
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)

  /// Socket option for disabling the Nagle algorithm.
  /**
   * Implements the IPPROTO_TCP/TCP_NODELAY socket option.
   *
   * @par Examples
   * Setting the option:
   * @code
   * boost::asio::ip::tcp::socket socket(io_service); 
   * ...
   * boost::asio::ip::tcp::no_delay option(true);
   * socket.set_option(option);
   * @endcode
   *
   * @par
   * Getting the current option value:
   * @code
   * boost::asio::ip::tcp::socket socket(io_service); 
   * ...
   * boost::asio::ip::tcp::no_delay option;
   * socket.get_option(option);
   * bool is_set = option.value();
   * @endcode
   *
   * @par Concepts:
   * Socket_Option, Boolean_Socket_Option.
   */
#if defined(GENERATING_DOCUMENTATION)
  typedef implementation_defined no_delay;
#else
  typedef boost::asio::detail::socket_option::boolean<
    BOOST_ASIO_OS_DEF(IPPROTO_TCP), BOOST_ASIO_OS_DEF(TCP_NODELAY)> no_delay;
#endif

  /// Compare two protocols for equality.
  friend bool operator==(const tcp& p1, const tcp& p2)
  {
    return p1.family_ == p2.family_;
  }

  /// Compare two protocols for inequality.
  friend bool operator!=(const tcp& p1, const tcp& p2)
  {
    return p1.family_ != p2.family_;
  }

private:
  // Construct with a specific family.
  explicit tcp(int protocol_family)
    : family_(protocol_family)
  {
  }

  int family_;
};

} // namespace ip
} // namespace asio
} // namespace boost

#include <boost/asio/detail/pop_options.hpp>

#endif // BOOST_ASIO_IP_TCP_HPP

以上就是 tcp 的全部代码 从代码中 可以看出

  /// The type of a TCP endpoint.
  typedef basic_endpoint<tcp> endpoint;

  /// The TCP socket type.
  typedef basic_stream_socket<tcp> socket;

  /// The TCP acceptor type.
  typedef basic_socket_acceptor<tcp> acceptor;

  /// The TCP resolver type.
  typedef basic_resolver<tcp> resolver;

tcp 涵括了 endpoint, socket, acceptor, resolver, 这么几个东西,不应该说是模板特化。也就是说 有关 tcp 的网络操作,都涵盖在这几个类成员里了。

下面我们来看看 v4() 和 v6() 这两个函数都干嘛去了。

  /// Construct to represent the IPv4 TCP protocol.
  static tcp v4()
  {
    return tcp(BOOST_ASIO_OS_DEF(AF_INET));
  }

  /// Construct to represent the IPv6 TCP protocol.
  static tcp v6()
  {
    return tcp(BOOST_ASIO_OS_DEF(AF_INET6));
  }

从函数上的注释来看 Construct to represent the IPv4 TCP protocol.
/// Construct to represent the IPv6 TCP protocol.
这两个函数 分别构造了 ipv4, ipv6 的实例。
至于 AF_INET,AF_INET6,分别代表的 ipv4, ipv6 协议。
好, 至此 tcp 就差不多看完了。哈哈 浅尝辄止就好。

那么下面这两句就好理解了

boost::asio::ip::tcp::endpoint endpoint(protocol, 9999);
boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);
log("Service Start !");
while (true) {
    boost::asio::ip::tcp::socket socket(io_service);
    acceptor.accept(socket);
    log("Client Connected !");
    boost::system::error_code error;
    socket.write_some(boost::asio::buffer("Hello World"), error);
}

创建了 一个 endpoint(端点) 实例
创建了 一个 acceptor(接收器) 实例
创建了 一个 socket (插座) 实例
acceptor 监听客户端的 socket 的连接(同步 阻塞);
一旦有客户端连接上了。就通过 socket 发送字符。
一下子看了这么多,是不是有点累了。今天就到这里吧。关于 endpoint,acceptor ,socket ,boost::asio::buffer() 我们在后面的文章中再讨论。
欢迎大佬批评文章中的不足之处,以便我早日改正,进步。

相关文章

网友评论

      本文标题:boost_asio学习第3课 helloworld 服务端

      本文链接:https://www.haomeiwen.com/subject/jrhkwxtx.html