asio库支持TCP、UDP和工CMP等通信协议,它在名字空间boost::asio :: ip里提供了大量的网络通信方面的函数和类,很好地封装了原始的Socket API,展现给asio用户一个方便易用且健壮的网络通信库,下面的论述主要针对使用最广泛的TCP协议。
类ip ::tcp是asio网络通信(TCP)部分主要的类,表示TCP协议。但它本身并没有太多的功能,而是定义了数个用于TCP通信的typedef类型,用来协作完成网络通信。这些typedef包括端点类endpoint、套接字类socket、流类iostream,以及接受器acceptor、解析器resolver等。从某种程度上来看,ip::tcp类更像是一个名字空间。
class tcp
{
public:
/// The type of a TCP endpoint.
typedef basic_endpoint<tcp> endpoint;
/// Construct to represent the IPv4 TCP protocol.
static tcp v4() BOOST_ASIO_NOEXCEPT
{
return tcp(BOOST_ASIO_OS_DEF(AF_INET));
}
/// Construct to represent the IPv6 TCP protocol.
static tcp v6() BOOST_ASIO_NOEXCEPT
{
return tcp(BOOST_ASIO_OS_DEF(AF_INET6));
}
/// Obtain an identifier for the type of the protocol.
int type() const BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_OS_DEF(SOCK_STREAM);
}
/// Obtain an identifier for the protocol.
int protocol() const BOOST_ASIO_NOEXCEPT
{
return BOOST_ASIO_OS_DEF(IPPROTO_TCP);
}
/// Obtain an identifier for the protocol family.
int family() const BOOST_ASIO_NOEXCEPT
{
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(my_context);
* ...
* 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(my_context);
* ...
* 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) BOOST_ASIO_NOEXCEPT
: family_(protocol_family)
{
}
int family_;
};
ip : :tcp 的内部类型endpoint、socket、acceptor和 resolver是 asio库TCP通信中最核心的一组类,它们封装了socket 的连接、断开、数据收发和地址解析等功能,使用它们可以很容易地编写出socket程序。
address
IP卫地址独立于TCP、UDP等通信协议,asio库使用类ip : : address来表示IP地址;可以同时支持工Pv4和工Pv6两种地址,它的类摘要如下:
class address
{
public:
address();
address(const address&other);
bool is_v4();
bool is_v6();
bool is_loopback();//环回地址
ip::address_v4 to_v4()const;
ip::address_v6 to_v6()const;
string to_string();
static address from_string(const char* str);
static address from_string(const string& str);
....
}
addreee类最重要的方法是静态成员函数from_string (),它是一个工厂函数,可以从字符串产生IP地址,地址的版本则可以用is_v4()和is_v6()来检测。相应地,address也有一个to_string ()函数,可以把工F地址转换为字符串。
示例:
ip::address addr;
addr=addr.from_strng("127.0.0.1");
assert(addrss.is_v4());
endpoint
有了IP地址,再加上通信用的端口号就构成了一个socket端点,在asio库中用ip: :tcp: :endpoint来表示。
template<typename InternetProtocol>
class basic_endpoint{
typedef InternetProtocol protocol_type;
basic_endpoint(const InternetProtocol&internet_protocol,
unsigned short port_num);
basic_endpoint(const ip::address&addr, unsigned short port_num)
basic_endpoint(basic_endpoint&&other);
basic_endpoint&operator==(const basic_endpoint&other);
protocol_type protocol();
unsigned short port()const;
....
}
endpoint的主要用法是通过构造函数创建一个可用于socket通信的端点对象,端点的地址和端口号可以用address ()和 port()获得,例如:
ip::address addr;
addr=addr.from_string("127.0.0.1");
ip::tcp::endpoint(addr,6688)
socket
template<typename Protocol,typename ...AS>
class basic_stream_socket
{
public:
typedef Protocol Protocol_type;
typedef typename Protocol::endpoint endpoint_type;
//
basic_stream_socket(io_service&io);
basic_stream_socket(io_service&io,
const Protocol_type&Protocol);
basic_stream_socket(io_service&io,
const endpoint_type& endpoint);
//打开
void open(const Protocol_type&protocol==Protocol_type());
bool is_open()const;
void close();
void shutdown();
void cancel();
//可读字节数
std::size_t available()const;
//绑定endpoint;
void connect(const endpoint_type&peer_endpoint)
void connect(const endpoint_type&peer_endpoint,handler);
//设置socket
void set_option(const SettableSocketOptions&option);
void get_option(GettableSocketOption&option);
...
//发送数据
std::size receive(const MutableBuffer*buffer);
void async_receive(const MutableBuffer*buffer,handler);
...
};
socket可以在构造时就指定使用的协议或者endpoint,或者稍后调用成员函数connect ()。连接成功后可以用local_endpoint()和remote_endpoint()获得连接两端的端点信息,用 available ()获取可读取的字节数,用 receive ( )/read _some ( )和send ( ) /write_some ( )读写数据,当操作完成后使用close ()函数关闭socket。如果不关闭socket,那么在 socket对象析构时也会自动调用close()关闭。
accptor
acceptor类对应Socket API的 accept ()函数功能,它用于服务器端,在指定的端口号接受连接,必须配合socket类才能完成通信。
template<typename Protocol,typename... AS>
class basic_socket_acceptor
{
public:
typedef Protocol protocl_type;
typedef typename Protocol::endpoint endpoint_type;
//
explicit basic_socket_acceptor(io_service&io_service);
basic_socket_acceptor(io_service&io_service,
const protocol_type&protocol);
//
accept(socket &peer);
void async_accept(socket&peer,handler);
...
};
acceptor可以像传统socket API那样使用,open()打开端口,bind ()绑定再用listen ()监听端口,但更方便的是使用它的构造函数,传入endpoint直接完成这三个动作在开始监听之后,调用accept ()就可以接受新的连接,连接成功的socket在函数参数里以引用的形式输出。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/129666.html