Skip to content

Commit 7d5b259

Browse files
[io] socket.
1 parent 23a602c commit 7d5b259

File tree

6 files changed

+470
-0
lines changed

6 files changed

+470
-0
lines changed

Diff for: CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ else()
181181
src/io/random_access_file.cpp
182182
src/io/stream_file.cpp
183183
src/io/endpoint.cpp
184+
src/io/socket.cpp
184185
)
185186

186187
target_link_libraries(boost_cobalt_io PUBLIC boost_cobalt)

Diff for: build/Jamfile

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ alias cobalt_io_sources
7878
io/random_access_file.cpp
7979
io/stream_file.cpp
8080
io/endpoint.cpp
81+
io/socket.cpp
8182
;
8283

8384

Diff for: doc/index.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ include::reference/io/stream_file.adoc[]
9595
include::reference/io/random_access_file.adoc[]
9696
include::reference/io/serial_port.adoc[]
9797
include::reference/io/endpoint.adoc[]
98+
include::reference/io/socket.adoc[]
9899

99100
= In-Depth
100101

Diff for: doc/reference/io/socket.adoc

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
== cobalt/io/socket.hpp
2+
3+
The socket class is the base for any socket.
4+
5+
[source,cpp]
6+
----
7+
8+
struct socket
9+
{
10+
[[nodiscard]] system::result<void> open(protocol_type prot = protocol_type {});
11+
[[nodiscard]] system::result<void> close();
12+
[[nodiscard]] system::result<void> cancel();
13+
[[nodiscard]] bool is_open() const;
14+
15+
// asio acceptor compatibility
16+
template<typename T>
17+
struct rebind_executor {using other = socket;};
18+
19+
using shutdown_type = asio::socket_base::shutdown_type;
20+
using wait_type = asio::socket_base::wait_type;
21+
using message_flags = asio::socket_base::message_flags;
22+
constexpr static int message_peek = asio::socket_base::message_peek;
23+
constexpr static int message_out_of_band = asio::socket_base::message_out_of_band;
24+
constexpr static int message_do_not_route = asio::socket_base::message_do_not_route;
25+
constexpr static int message_end_of_record = asio::socket_base::message_end_of_record;
26+
27+
using native_handle_type = asio::basic_socket<protocol_type, executor>::native_handle_type;
28+
native_handle_type native_handle();
29+
30+
// Drop the connection
31+
[[nodiscard]] system::result<void> shutdown(shutdown_type = shutdown_type::shutdown_both);
32+
33+
// endpoint of a connected endpiotn
34+
[[nodiscard]] system::result<endpoint> local_endpoint() const;
35+
[[nodiscard]] system::result<endpoint> remote_endpoint() const;
36+
37+
38+
system::result<void> assign(protocol_type protocol, native_handle_type native_handle);
39+
system::result<native_handle_type> release();
40+
41+
/// socket options
42+
[[nodiscard]] system::result<std::size_t> bytes_readable();
43+
44+
[[nodiscard]] system::result<void> set_debug(bool debug);
45+
[[nodiscard]] system::result<bool> get_debug() const;
46+
47+
[[nodiscard]] system::result<void> set_do_not_route(bool do_not_route);
48+
[[nodiscard]] system::result<bool> get_do_not_route() const;
49+
50+
[[nodiscard]] system::result<void> set_enable_connection_aborted(bool enable_connection_aborted);
51+
[[nodiscard]] system::result<bool> get_enable_connection_aborted() const;
52+
53+
[[nodiscard]] system::result<void> set_keep_alive(bool keep_alive);
54+
[[nodiscard]] system::result<bool> get_keep_alive() const;
55+
56+
[[nodiscard]] system::result<void> set_linger(bool linger, int timeout);
57+
[[nodiscard]] system::result<std::pair<bool, int>> get_linger() const;
58+
59+
[[nodiscard]] system::result<void> set_receive_buffer_size(std::size_t receive_buffer_size);
60+
[[nodiscard]] system::result<std::size_t> get_receive_buffer_size() const;
61+
62+
[[nodiscard]] system::result<void> set_send_buffer_size(std::size_t send_buffer_size);
63+
[[nodiscard]] system::result<std::size_t> get_send_buffer_size() const;
64+
65+
[[nodiscard]] system::result<void> set_receive_low_watermark(std::size_t receive_low_watermark);
66+
[[nodiscard]] system::result<std::size_t> get_receive_low_watermark() const;
67+
68+
[[nodiscard]] system::result<void> set_send_low_watermark(std::size_t send_low_watermark);
69+
[[nodiscard]] system::result<std::size_t> get_send_low_watermark() const;
70+
71+
[[nodiscard]] system::result<void> set_reuse_address(bool reuse_address);
72+
[[nodiscard]] system::result<bool> get_reuse_address() const;
73+
74+
[[nodiscard]] system::result<void> set_no_delay(bool reuse_address);
75+
[[nodiscard]] system::result<bool> get_no_delay() const;
76+
77+
78+
wait_op wait(wait_type wt = wait_type::wait_read);
79+
// Connect to a specific endpoint
80+
connect_op connect(endpoint ep);
81+
// connect to one of the given endpoints. Returns the one connected to.
82+
ranged_connect_op connect(endpoint_sequence ep);
83+
84+
protected:
85+
// Adopt the under-specified endpoint. E.g. to tcp from an endpoint specified as ip_address
86+
virtual void adopt_endpoint_(endpoint & ) {}
87+
88+
};
89+
90+
// Connect to sockets using the given protocol
91+
system::result<void> connect_pair(protocol_type protocol, socket & socket1, socket & socket2);
92+
93+
----

Diff for: include/boost/cobalt/io/socket.hpp

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//
2+
// Copyright (c) 2024 Klemens Morgenstern ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
8+
#ifndef BOOST_COBALT_EXPERIMENTAL_IO_SOCKET_HPP
9+
#define BOOST_COBALT_EXPERIMENTAL_IO_SOCKET_HPP
10+
11+
#include <boost/cobalt/io/endpoint.hpp>
12+
#include <boost/cobalt/io/ops.hpp>
13+
#include <boost/asio/socket_base.hpp>
14+
#include <boost/asio/basic_socket.hpp>
15+
16+
17+
namespace boost::cobalt::io
18+
{
19+
20+
struct socket
21+
{
22+
[[nodiscard]] system::result<void> open(protocol_type prot = protocol_type {});
23+
[[nodiscard]] system::result<void> close();
24+
[[nodiscard]] system::result<void> cancel();
25+
[[nodiscard]] bool is_open() const;
26+
27+
// asio acceptor compatibility
28+
template<typename T>
29+
struct rebind_executor {using other = socket;};
30+
31+
using shutdown_type = asio::socket_base::shutdown_type;
32+
using wait_type = asio::socket_base::wait_type;
33+
using message_flags = asio::socket_base::message_flags;
34+
constexpr static int message_peek = asio::socket_base::message_peek;
35+
constexpr static int message_out_of_band = asio::socket_base::message_out_of_band;
36+
constexpr static int message_do_not_route = asio::socket_base::message_do_not_route;
37+
constexpr static int message_end_of_record = asio::socket_base::message_end_of_record;
38+
39+
using native_handle_type = asio::basic_socket<protocol_type, executor>::native_handle_type;
40+
native_handle_type native_handle();
41+
42+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> shutdown(shutdown_type = shutdown_type::shutdown_both);
43+
44+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<endpoint> local_endpoint() const;
45+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<endpoint> remote_endpoint() const;
46+
47+
48+
BOOST_COBALT_IO_DECL system::result<void> assign(protocol_type protocol, native_handle_type native_handle);
49+
BOOST_COBALT_IO_DECL system::result<native_handle_type> release();
50+
51+
/// copied from what asio does
52+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::size_t> bytes_readable();
53+
54+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_debug(bool debug);
55+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_debug() const;
56+
57+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_do_not_route(bool do_not_route);
58+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_do_not_route() const;
59+
60+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_enable_connection_aborted(bool enable_connection_aborted);
61+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_enable_connection_aborted() const;
62+
63+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_keep_alive(bool keep_alive);
64+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_keep_alive() const;
65+
66+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_linger(bool linger, int timeout);
67+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::pair<bool, int>> get_linger() const;
68+
69+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_receive_buffer_size(std::size_t receive_buffer_size);
70+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::size_t> get_receive_buffer_size() const;
71+
72+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_send_buffer_size(std::size_t send_buffer_size);
73+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::size_t> get_send_buffer_size() const;
74+
75+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_receive_low_watermark(std::size_t receive_low_watermark);
76+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::size_t> get_receive_low_watermark() const;
77+
78+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_send_low_watermark(std::size_t send_low_watermark);
79+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<std::size_t> get_send_low_watermark() const;
80+
81+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_reuse_address(bool reuse_address);
82+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_reuse_address() const;
83+
84+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<void> set_no_delay(bool reuse_address);
85+
[[nodiscard]] BOOST_COBALT_IO_DECL system::result<bool> get_no_delay() const;
86+
87+
struct [[nodiscard]] wait_op final : op<system::error_code>
88+
{
89+
wait_type wt;
90+
91+
BOOST_COBALT_IO_DECL
92+
void ready(boost::cobalt::handler<system::error_code>) final;
93+
BOOST_COBALT_IO_DECL
94+
void initiate(boost::cobalt::completion_handler<system::error_code>) final;
95+
96+
wait_op(wait_type wt, socket & sock) :
97+
wt(wt), sock_(sock) {}
98+
99+
private:
100+
socket & sock_;
101+
102+
};
103+
wait_op wait(wait_type wt = wait_type::wait_read)
104+
{
105+
return {wt, *this};
106+
}
107+
108+
struct [[nodiscard]] connect_op final : op<system::error_code>
109+
{
110+
struct endpoint endpoint;
111+
112+
BOOST_COBALT_IO_DECL
113+
void initiate(boost::cobalt::completion_handler<system::error_code>) final;
114+
115+
connect_op(struct endpoint endpoint, socket & socket) :
116+
endpoint(endpoint), sock_(socket) {}
117+
private:
118+
socket & sock_;
119+
};
120+
connect_op connect(endpoint ep)
121+
{
122+
return {ep, *this};
123+
}
124+
125+
126+
struct [[nodiscard]] ranged_connect_op final : op<system::error_code, endpoint>
127+
{
128+
endpoint_sequence endpoints;
129+
130+
BOOST_COBALT_IO_DECL
131+
void initiate(boost::cobalt::completion_handler<system::error_code, endpoint>) final;
132+
133+
ranged_connect_op(endpoint_sequence eps, socket & socket) :
134+
endpoints(eps), sock_(socket) {}
135+
private:
136+
socket & sock_;
137+
};
138+
ranged_connect_op connect(endpoint_sequence ep)
139+
{
140+
return {std::move(ep), *this};
141+
}
142+
143+
144+
protected:
145+
virtual void adopt_endpoint_(endpoint & ) {}
146+
socket(asio::basic_socket<protocol_type, executor> & socket) : socket_(socket) {}
147+
private:
148+
149+
friend struct acceptor;
150+
asio::basic_socket<protocol_type, executor> & socket_;
151+
};
152+
153+
BOOST_COBALT_IO_DECL system::result<void> connect_pair(protocol_type protocol, socket & socket1, socket & socket2);
154+
155+
156+
}
157+
158+
#endif //BOOST_COBALT_EXPERIMENTAL_IO_SOCKET_HPP

0 commit comments

Comments
 (0)