Chat Tigré
Chat Tigré

Reputation: 1

boost asio basic_socket issue

I am a game developer. I encounter this problem when I was developing a chatting feature. My game got crash when running on Iphone and it's caused by basic_socket::close in asio lib. Here is source code:

  /// Close the socket.
  /**
   * This function is used to close the socket. Any asynchronous send, receive
   * or connect operations will be cancelled immediately, and will complete
   * with the boost::asio::error::operation_aborted error.
   *
   * @throws boost::system::system_error Thrown on failure. Note that, even if
   * the function indicates an error, the underlying descriptor is closed.
   *
   * @note For portable behaviour with respect to graceful closure of a
   * connected socket, call shutdown() before closing the socket.
   */
  void close()
  {
    boost::system::error_code ec;
    this->get_service().close(this->get_implementation(), ec);
    boost::asio::detail::throw_error(ec, "close");
  }

so here is my question, why does it always throw a exception? (btw, if you don't use exception feature on boost, the throw_error method will call std::terminate() finally, which will make the program crashed.)

---------------------------update-----------------------------

my game may close the http request and restart it. when it closes the request, it will go here to close the socket. I just don't know why it throws a exception when close, I think it is unnecessary, isn't it?

I have solve the issue which caused by the exception with try & catch. within no-use exception situation in boost, I call std::set_terminate() to avoid crash. So I don't ask for a solution, I ask for why :)

Upvotes: 0

Views: 896

Answers (1)

Tanner Sansbury
Tanner Sansbury

Reputation: 51871

basic_socket::close() is thin wrapper around the OS specific ::close() or ::closesocket() call. The iOS documentation for ::close() states it will fail if:

  • [EBADF] - not a valid, active file descriptor.
  • [EINTR] - execution was interrupted by a signal.
  • [EIO] - a previously-uncommitted write encountered an input/output error.

Examine the exception or error_code to determine the type of failure.


As recommended in the Boost.Asio basic_socket::close() documentation, one should consider invoking shutdown() before closing the socket to obtain portable behavior on graceful closure. Furthermore, consider using the non-throwing overloads for functions, such as this basic_socket::close(ec) overload:

boost::asio::ip::tcp::socket socket(io_service);
boost::system::error_code error;
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
if (error)
{
  // An error occurred.
}

socket.close(error);
if (error)
{
  // An error occurred.
}

Upvotes: 1

Related Questions