== cobalt/io/socket.hpp

The socket class is the base for any socket.

[source,cpp]
----

struct socket
{
  [[nodiscard]] system::result<void> open(protocol_type prot = protocol_type {});
  [[nodiscard]] system::result<void> close();
  [[nodiscard]] system::result<void> cancel();
  [[nodiscard]] bool is_open() const;

  // asio acceptor compatibility
  template<typename T>
  struct rebind_executor {using other = socket;};

  using shutdown_type      = asio::socket_base::shutdown_type;
  using wait_type          = asio::socket_base::wait_type;
  using message_flags      = asio::socket_base::message_flags;
  constexpr static int message_peek          = asio::socket_base::message_peek;
  constexpr static int message_out_of_band   = asio::socket_base::message_out_of_band;
  constexpr static int message_do_not_route  = asio::socket_base::message_do_not_route;
  constexpr static int message_end_of_record = asio::socket_base::message_end_of_record;

  using native_handle_type = asio::basic_socket<protocol_type, executor>::native_handle_type;
  native_handle_type native_handle();

  // Drop the connection
  [[nodiscard]] system::result<void> shutdown(shutdown_type = shutdown_type::shutdown_both);

  // endpoint of a connected endpiotn
  [[nodiscard]] system::result<endpoint> local_endpoint() const;
  [[nodiscard]] system::result<endpoint> remote_endpoint() const;


  system::result<void> assign(protocol_type protocol, native_handle_type native_handle);
  system::result<native_handle_type> release();

  /// socket options
  [[nodiscard]] system::result<std::size_t> bytes_readable();

  [[nodiscard]] system::result<void> set_debug(bool debug);
  [[nodiscard]] system::result<bool> get_debug() const;

  [[nodiscard]] system::result<void> set_do_not_route(bool do_not_route);
  [[nodiscard]] system::result<bool> get_do_not_route() const;

  [[nodiscard]] system::result<void> set_enable_connection_aborted(bool enable_connection_aborted);
  [[nodiscard]] system::result<bool> get_enable_connection_aborted() const;

  [[nodiscard]] system::result<void> set_keep_alive(bool keep_alive);
  [[nodiscard]] system::result<bool> get_keep_alive() const;

  [[nodiscard]] system::result<void> set_linger(bool linger, int timeout);
  [[nodiscard]] system::result<std::pair<bool, int>> get_linger() const;

  [[nodiscard]] system::result<void>        set_receive_buffer_size(std::size_t receive_buffer_size);
  [[nodiscard]] system::result<std::size_t> get_receive_buffer_size() const;

  [[nodiscard]] system::result<void>        set_send_buffer_size(std::size_t send_buffer_size);
  [[nodiscard]] system::result<std::size_t> get_send_buffer_size() const;

  [[nodiscard]] system::result<void>        set_receive_low_watermark(std::size_t receive_low_watermark);
  [[nodiscard]] system::result<std::size_t> get_receive_low_watermark() const;

  [[nodiscard]] system::result<void>        set_send_low_watermark(std::size_t send_low_watermark);
  [[nodiscard]] system::result<std::size_t> get_send_low_watermark() const;

  [[nodiscard]] system::result<void> set_reuse_address(bool reuse_address);
  [[nodiscard]] system::result<bool> get_reuse_address() const;

  [[nodiscard]] system::result<void> set_no_delay(bool reuse_address);
  [[nodiscard]] system::result<bool> get_no_delay() const;


  wait_op     wait(wait_type wt = wait_type::wait_read);
  // Connect to a specific endpoint
  connect_op connect(endpoint ep);
  // connect to one of the given endpoints. Returns the one connected to.
  ranged_connect_op connect(endpoint_sequence ep);

 protected:
  // Adopt the under-specified endpoint. E.g. to tcp from an endpoint specified as ip_address
  virtual void adopt_endpoint_(endpoint & ) {}

};

// Connect to sockets using the given protocol
system::result<void> connect_pair(protocol_type protocol, socket & socket1, socket & socket2);

----

