⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_iocp_socket_service.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 5 页
字号:
      ec = boost::asio::error::operation_not_supported;    }#else // defined(BOOST_ASIO_ENABLE_CANCELIO)    else    {      // Cancellation is not supported as CancelIo may not be used.      ec = boost::asio::error::operation_not_supported;    }#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)    return ec;  }  // Determine whether the socket is at the out-of-band data mark.  bool at_mark(const implementation_type& impl,      boost::system::error_code& ec) const  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return false;    }    boost::asio::detail::ioctl_arg_type value = 0;    socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec);    return ec ? false : value != 0;  }  // Determine the number of bytes available for reading.  std::size_t available(const implementation_type& impl,      boost::system::error_code& ec) const  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return 0;    }    boost::asio::detail::ioctl_arg_type value = 0;    socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec);    return ec ? static_cast<std::size_t>(0) : static_cast<std::size_t>(value);  }  // Bind the socket to the specified local endpoint.  boost::system::error_code bind(implementation_type& impl,      const endpoint_type& endpoint, boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return ec;    }    socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);    return ec;  }  // Place the socket into the state where it will listen for new connections.  boost::system::error_code listen(implementation_type& impl, int backlog,      boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return ec;    }    socket_ops::listen(impl.socket_, backlog, ec);    return ec;  }  // Set a socket option.  template <typename Option>  boost::system::error_code set_option(implementation_type& impl,      const Option& option, boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return ec;    }    if (option.level(impl.protocol_) == custom_socket_option_level        && option.name(impl.protocol_) == enable_connection_aborted_option)    {      if (option.size(impl.protocol_) != sizeof(int))      {        ec = boost::asio::error::invalid_argument;      }      else      {        if (*reinterpret_cast<const int*>(option.data(impl.protocol_)))          impl.flags_ |= implementation_type::enable_connection_aborted;        else          impl.flags_ &= ~implementation_type::enable_connection_aborted;        ec = boost::system::error_code();      }      return ec;    }    else    {      if (option.level(impl.protocol_) == SOL_SOCKET          && option.name(impl.protocol_) == SO_LINGER)      {        const ::linger* linger_option =          reinterpret_cast<const ::linger*>(option.data(impl.protocol_));        if (linger_option->l_onoff != 0 && linger_option->l_linger != 0)          impl.flags_ |= implementation_type::close_might_block;        else          impl.flags_ &= ~implementation_type::close_might_block;      }      socket_ops::setsockopt(impl.socket_,          option.level(impl.protocol_), option.name(impl.protocol_),          option.data(impl.protocol_), option.size(impl.protocol_), ec);      return ec;    }  }  // Set a socket option.  template <typename Option>  boost::system::error_code get_option(const implementation_type& impl,      Option& option, boost::system::error_code& ec) const  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return ec;    }    if (option.level(impl.protocol_) == custom_socket_option_level        && option.name(impl.protocol_) == enable_connection_aborted_option)    {      if (option.size(impl.protocol_) != sizeof(int))      {        ec = boost::asio::error::invalid_argument;      }      else      {        int* target = reinterpret_cast<int*>(option.data(impl.protocol_));        if (impl.flags_ & implementation_type::enable_connection_aborted)          *target = 1;        else          *target = 0;        option.resize(impl.protocol_, sizeof(int));        ec = boost::system::error_code();      }      return ec;    }    else    {      size_t size = option.size(impl.protocol_);      socket_ops::getsockopt(impl.socket_,          option.level(impl.protocol_), option.name(impl.protocol_),          option.data(impl.protocol_), &size, ec);      if (!ec)        option.resize(impl.protocol_, size);      return ec;    }  }  // Perform an IO control command on the socket.  template <typename IO_Control_Command>  boost::system::error_code io_control(implementation_type& impl,      IO_Control_Command& command, boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return ec;    }    socket_ops::ioctl(impl.socket_, command.name(),        static_cast<ioctl_arg_type*>(command.data()), ec);    if (!ec && command.name() == static_cast<int>(FIONBIO))    {      if (command.get())        impl.flags_ |= implementation_type::user_set_non_blocking;      else        impl.flags_ &= ~implementation_type::user_set_non_blocking;    }    return ec;  }  // Get the local endpoint.  endpoint_type local_endpoint(const implementation_type& impl,      boost::system::error_code& ec) const  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return endpoint_type();    }    endpoint_type endpoint;    std::size_t addr_len = endpoint.capacity();    if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))      return endpoint_type();    endpoint.resize(addr_len);    return endpoint;  }  // Get the remote endpoint.  endpoint_type remote_endpoint(const implementation_type& impl,      boost::system::error_code& ec) const  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return endpoint_type();    }    if (impl.socket_.have_remote_endpoint())    {      // Check if socket is still connected.      DWORD connect_time = 0;      size_t connect_time_len = sizeof(connect_time);      if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_CONNECT_TIME,            &connect_time, &connect_time_len, ec) == socket_error_retval)      {        return endpoint_type();      }      if (connect_time == 0xFFFFFFFF)      {        ec = boost::asio::error::not_connected;        return endpoint_type();      }      ec = boost::system::error_code();      return impl.socket_.remote_endpoint();    }    else    {      endpoint_type endpoint;      std::size_t addr_len = endpoint.capacity();      if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))        return endpoint_type();      endpoint.resize(addr_len);      return endpoint;    }  }  /// Disable sends or receives on the socket.  boost::system::error_code shutdown(implementation_type& impl,      socket_base::shutdown_type what, boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return ec;    }    socket_ops::shutdown(impl.socket_, what, ec);    return ec;  }  // Send the given data to the peer. Returns the number of bytes sent.  template <typename ConstBufferSequence>  size_t send(implementation_type& impl, const ConstBufferSequence& buffers,      socket_base::message_flags flags, boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return 0;    }    // Copy buffers into WSABUF array.    ::WSABUF bufs[max_buffers];    typename ConstBufferSequence::const_iterator iter = buffers.begin();    typename ConstBufferSequence::const_iterator end = buffers.end();    DWORD i = 0;    size_t total_buffer_size = 0;    for (; iter != end && i < max_buffers; ++iter, ++i)    {      boost::asio::const_buffer buffer(*iter);      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));      bufs[i].buf = const_cast<char*>(          boost::asio::buffer_cast<const char*>(buffer));      total_buffer_size += boost::asio::buffer_size(buffer);    }    // A request to receive 0 bytes on a stream socket is a no-op.    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)    {      ec = boost::system::error_code();      return 0;    }    // Send the data.    DWORD bytes_transferred = 0;    int result = ::WSASend(impl.socket_, bufs,        i, &bytes_transferred, flags, 0, 0);    if (result != 0)    {      DWORD last_error = ::WSAGetLastError();      if (last_error == ERROR_NETNAME_DELETED)        last_error = WSAECONNRESET;      else if (last_error == ERROR_PORT_UNREACHABLE)        last_error = WSAECONNREFUSED;      ec = boost::system::error_code(last_error,          boost::asio::error::get_system_category());      return 0;    }    ec = boost::system::error_code();    return bytes_transferred;  }  // Wait until data can be sent without blocking.  size_t send(implementation_type& impl, const null_buffers&,      socket_base::message_flags, boost::system::error_code& ec)  {    if (!is_open(impl))    {      ec = boost::asio::error::bad_descriptor;      return 0;    }    // Wait for socket to become ready.    socket_ops::poll_write(impl.socket_, ec);    return 0;  }  template <typename ConstBufferSequence, typename Handler>  class send_operation    : public operation  {  public:    send_operation(win_iocp_io_service& io_service,        weak_cancel_token_type cancel_token,        const ConstBufferSequence& buffers, Handler handler)      : operation(io_service,          &send_operation<ConstBufferSequence, Handler>::do_completion_impl,          &send_operation<ConstBufferSequence, Handler>::destroy_impl),        work_(io_service.get_io_service()),        cancel_token_(cancel_token),        buffers_(buffers),        handler_(handler)    {    }  private:    static void do_completion_impl(operation* op,        DWORD last_error, size_t bytes_transferred)    {      // Take ownership of the operation object.      typedef send_operation<ConstBufferSequence, Handler> op_type;      op_type* handler_op(static_cast<op_type*>(op));      typedef handler_alloc_traits<Handler, op_type> alloc_traits;      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)      // Check whether buffers are still valid.      typename ConstBufferSequence::const_iterator iter        = handler_op->buffers_.begin();      typename ConstBufferSequence::const_iterator end        = handler_op->buffers_.end();      while (iter != end)      {        boost::asio::const_buffer buffer(*iter);        boost::asio::buffer_cast<const char*>(buffer);        ++iter;      }#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)      // Map non-portable errors to their portable counterparts.      boost::system::error_code ec(last_error,          boost::asio::error::get_system_category());      if (ec.value() == ERROR_NETNAME_DELETED)      {        if (handler_op->cancel_token_.expired())          ec = boost::asio::error::operation_aborted;        else          ec = boost::asio::error::connection_reset;      }      else if (ec.value() == ERROR_PORT_UNREACHABLE)      {        ec = boost::asio::error::connection_refused;      }      // Make a copy of the handler so that the memory can be deallocated before      // the upcall is made.      Handler handler(handler_op->handler_);      // Free the memory associated with the handler.      ptr.reset();      // Call the handler.      boost_asio_handler_invoke_helpers::invoke(          detail::bind_handler(handler, ec, bytes_transferred), &handler);    }    static void destroy_impl(operation* op)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -