Program Listing for File base_socket.ipp¶
↰ Return to documentation for file (stream-client/stream/impl/base_socket.ipp
)
#pragma once
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/socket_base.hpp>
namespace stream_client {
template <typename Socket>
base_socket<Socket>::base_socket(const endpoint_type& peer_endpoint, time_duration_type connect_timeout,
time_duration_type operation_timeout)
: detail::steady_timed_base()
, socket_(get_io_service())
, connection_timeout_(std::move(connect_timeout))
, io_operation_timeout_(std::move(operation_timeout))
{
io_timeout_enabled(false);
const auto expiration = scope_expire(connection_timeout_);
boost::system::error_code ec = boost::asio::error::would_block;
socket_.async_connect(peer_endpoint, [&](const boost::system::error_code& error) {
if (this->deadline_fired_) {
ec = boost::asio::error::timed_out;
} else {
ec = error;
}
});
while (ec == boost::asio::error::would_block) {
get_io_service().run_one();
};
if (ec) {
if (ec == boost::asio::error::timed_out) {
throw boost::system::system_error{ec, "Socket connection timed out"};
}
throw boost::system::system_error{ec, "Socket connection failed"};
}
if (!socket_.is_open()) {
throw boost::system::system_error{boost::asio::error::operation_aborted, "Socket connection failed"};
}
set_option(boost::asio::socket_base::keep_alive(true));
if (std::is_same<protocol_type, boost::asio::ip::tcp>::value) {
set_option(boost::asio::ip::tcp::no_delay(true));
#if __linux__
set_option(boost::asio::detail::socket_option::boolean<IPPROTO_TCP, TCP_QUICKACK>(true));
#endif
}
io_timeout_enabled(true);
}
template <typename Socket>
base_socket<Socket>::base_socket(const config& cfg)
: base_socket(cfg.peer_endpoint, cfg.connect_timeout, cfg.operation_timeout)
{
}
template <typename Socket>
base_socket<Socket>::~base_socket()
{
boost::system::error_code ignored_ec;
close(ignored_ec);
}
template <typename Socket>
boost::system::error_code base_socket<Socket>::close()
{
boost::system::error_code ec;
next_layer().close(ec);
return ec;
}
template <typename Socket>
template <typename SettableSocketOption>
void base_socket<Socket>::set_option(const SettableSocketOption& option)
{
boost::system::error_code ec;
set_option(option, ec);
if (ec) {
throw boost::system::system_error{ec, "Socket set_option() failed"};
}
}
template <typename Socket>
template <typename GettableSocketOption>
void base_socket<Socket>::get_option(GettableSocketOption& option) const
{
boost::system::error_code ec;
get_option(option, ec);
if (ec) {
throw boost::system::system_error{ec, "Socket get_option() failed"};
}
}
template <typename Socket>
typename base_socket<Socket>::endpoint_type base_socket<Socket>::local_endpoint() const
{
boost::system::error_code ec;
auto endpoint = local_endpoint(ec);
if (ec) {
throw boost::system::system_error{ec, "Socket local_endpoint() failed"};
}
return endpoint;
}
template <typename Socket>
typename base_socket<Socket>::endpoint_type base_socket<Socket>::remote_endpoint() const
{
boost::system::error_code ec;
auto endpoint = remote_endpoint(ec);
if (ec) {
throw boost::system::system_error{ec, "Socket remote_endpoint() failed"};
}
return endpoint;
}
template <typename Socket>
void base_socket<Socket>::deadline_actor()
{
boost::system::error_code ignored_ec;
close(ignored_ec);
}
} // namespace stream_client