Skip to content

Commit 6557b5c

Browse files
[io] socket implementations.
1 parent 7d5b259 commit 6557b5c

16 files changed

+529
-4
lines changed

Diff for: CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ else()
182182
src/io/stream_file.cpp
183183
src/io/endpoint.cpp
184184
src/io/socket.cpp
185+
src/io/datagram_socket.cpp
186+
src/io/seq_packet_socket.cpp
187+
src/io/stream_socket.cpp
185188
)
186189

187190
target_link_libraries(boost_cobalt_io PUBLIC boost_cobalt)

Diff for: build/Jamfile

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ alias cobalt_io_sources
7979
io/stream_file.cpp
8080
io/endpoint.cpp
8181
io/socket.cpp
82+
io/datagram_socket.cpp
83+
io/seq_packet_socket.cpp
84+
io/stream_socket.cpp
8285
;
8386

8487

Diff for: doc/index.adoc

+3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ include::reference/io/random_access_file.adoc[]
9696
include::reference/io/serial_port.adoc[]
9797
include::reference/io/endpoint.adoc[]
9898
include::reference/io/socket.adoc[]
99+
include::reference/io/stream_socket.adoc[]
100+
include::reference/io/datagram_socket.adoc[]
101+
include::reference/io/seq_packet_socket.adoc[]
99102

100103
= In-Depth
101104

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

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
== cobalt/io/socket.hpp
2+
3+
This socket class implements a datagram socket, such as UDP.
4+
5+
[source,cpp]
6+
----
7+
8+
struct [[nodiscard]] datagram_socket final : socket
9+
{
10+
datagram_socket(const cobalt::executor & executor = this_thread::get_executor());
11+
datagram_socket(datagram_socket && lhs);
12+
datagram_socket(native_handle_type h, protocol_type protocol = protocol_type(),
13+
const cobalt::executor & executor = this_thread::get_executor());
14+
datagram_socket(endpoint ep,
15+
const cobalt::executor & executor = this_thread::get_executor());
16+
17+
write_op send(const_buffer_sequence buffer);
18+
read_op receive(mutable_buffer_sequence buffer);
19+
};
20+
21+
22+
// Create a pair of connected sockets.
23+
inline system::result<std::pair<datagram_socket, datagram_socket>> make_pair(decltype(local_datagram) protocol);
24+
----
25+

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

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
== cobalt/io/socket.hpp
2+
3+
The socket class for a seq packet socket, e.g. SCTP.
4+
5+
[source,cpp]
6+
----
7+
struct seq_packet_socket : socket
8+
{
9+
seq_packet_socket(const cobalt::executor & executor = this_thread::get_executor());
10+
seq_packet_socket(seq_packet_socket && lhs);
11+
seq_packet_socket(native_handle_type h, protocol_type protocol = protocol_type(),
12+
const executor & executor = this_thread::get_executor());
13+
seq_packet_socket(endpoint ep, const executor & executor = this_thread::get_executor());
14+
15+
receive_op receive(message_flags in_flags, message_flags& out_flags, mutable_buffer_sequence buffer);
16+
send_op send(message_flags in_flags, const_buffer_sequence buffer);
17+
receive_op receive(message_flags in_flags, mutable_buffer_sequence buffer);
18+
};
19+
20+
// Connect to sockets using the given protocol
21+
system::result<void> make_pair(decltype(local_seqpacket) protocol);
22+
----

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,5 @@ struct socket
9090
// Connect to sockets using the given protocol
9191
system::result<void> connect_pair(protocol_type protocol, socket & socket1, socket & socket2);
9292
93-
----
93+
----
94+

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

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
== cobalt/io/socket.hpp
2+
3+
The socket class for a seq packet socket, e.g. TCP.
4+
5+
[source,cpp]
6+
----
7+
8+
struct [[nodiscard]] stream_socket final : socket, stream
9+
{
10+
11+
stream_socket(const cobalt::executor & executor = this_thread::get_executor());
12+
stream_socket(stream_socket && lhs);
13+
stream_socket(native_handle_type h, protocol_type protocol = protocol_type(),
14+
const cobalt::executor & executor = this_thread::get_executor());
15+
stream_socket(endpoint ep,
16+
const cobalt::executor & executor = this_thread::get_executor());
17+
18+
write_op write_some(const_buffer_sequence buffer);
19+
read_op read_some(mutable_buffer_sequence buffer);};
20+
21+
// Connect to sockets using the given protocol
22+
inline system::result<std::pair<stream_socket, stream_socket>> make_pair(decltype(local_stream) protocol);
23+
24+
----
25+

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

+18
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,27 @@
99
#define BOOST_COBALT_IO_HPP
1010

1111
#include <boost/cobalt/io/buffer.hpp>
12+
#include <boost/cobalt/io/datagram_socket.hpp>
13+
#include <boost/cobalt/io/endpoint.hpp>
14+
#include <boost/cobalt/io/file.hpp>
1215
#include <boost/cobalt/io/ops.hpp>
16+
#include <boost/cobalt/io/pipe.hpp>
17+
#include <boost/cobalt/io/popen.hpp>
18+
#include <boost/cobalt/io/process.hpp>
19+
#include <boost/cobalt/io/random_access_device.hpp>
20+
#include <boost/cobalt/io/random_access_file.hpp>
21+
#include <boost/cobalt/io/read.hpp>
22+
#include <boost/cobalt/io/seq_packet_socket.hpp>
23+
#include <boost/cobalt/io/serial_port.hpp>
24+
#include <boost/cobalt/io/signal_set.hpp>
1325
#include <boost/cobalt/io/sleep.hpp>
26+
#include <boost/cobalt/io/socket.hpp>
1427
#include <boost/cobalt/io/steady_timer.hpp>
28+
#include <boost/cobalt/io/stream.hpp>
29+
#include <boost/cobalt/io/stream_file.hpp>
30+
#include <boost/cobalt/io/stream_socket.hpp>
1531
#include <boost/cobalt/io/system_timer.hpp>
32+
#include <boost/cobalt/io/write.hpp>
33+
1634

1735
#endif //BOOST_COBALT_IO_HPP

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

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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_IODATAGRAM_SOCKET_HPP
9+
#define BOOST_COBALT_IODATAGRAM_SOCKET_HPP
10+
11+
#include <boost/cobalt/io/endpoint.hpp>
12+
#include <boost/cobalt/io/socket.hpp>
13+
14+
#include <boost/asio/generic/datagram_protocol.hpp>
15+
#include <boost/asio/basic_datagram_socket.hpp>
16+
17+
namespace boost::cobalt::io
18+
{
19+
20+
struct [[nodiscard]] datagram_socket final : socket
21+
{
22+
BOOST_COBALT_IO_DECL datagram_socket(const cobalt::executor & executor = this_thread::get_executor());
23+
BOOST_COBALT_IO_DECL datagram_socket(datagram_socket && lhs);
24+
BOOST_COBALT_IO_DECL datagram_socket(native_handle_type h, protocol_type protocol = protocol_type(),
25+
const cobalt::executor & executor = this_thread::get_executor());
26+
BOOST_COBALT_IO_DECL datagram_socket(endpoint ep,
27+
const cobalt::executor & executor = this_thread::get_executor());
28+
29+
write_op send(const_buffer_sequence buffer)
30+
{
31+
return {buffer, this, initiate_send_};
32+
}
33+
read_op receive(mutable_buffer_sequence buffer)
34+
{
35+
return {buffer, this, initiate_receive_};
36+
}
37+
38+
private:
39+
BOOST_COBALT_IO_DECL void adopt_endpoint_(endpoint & ep) override;
40+
41+
BOOST_COBALT_IO_DECL static void initiate_receive_(void *, mutable_buffer_sequence, boost::cobalt::completion_handler<system::error_code, std::size_t>);
42+
BOOST_COBALT_IO_DECL static void initiate_send_ (void *, const_buffer_sequence, boost::cobalt::completion_handler<system::error_code, std::size_t>);
43+
44+
asio::basic_datagram_socket<protocol_type, executor> datagram_socket_;
45+
};
46+
47+
48+
inline system::result<std::pair<datagram_socket, datagram_socket>> make_pair(decltype(local_datagram) protocol)
49+
{
50+
std::pair<datagram_socket, datagram_socket> res;
51+
auto c = connect_pair(protocol, res.first, res.second);
52+
if (c)
53+
return res;
54+
else
55+
return c.error();
56+
}
57+
58+
}
59+
60+
#endif //BOOST_COBALT_IODATAGRAM_SOCKET_HPP

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

+6
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ constexpr static_protocol<AF_UNIX, BOOST_ASIO_OS_DEF(SOCK_D
120120
constexpr static_protocol<AF_UNIX, BOOST_ASIO_OS_DEF(SOCK_SEQPACKET)> local_seqpacket{};
121121
constexpr static_protocol<AF_UNIX> local_protocol {};
122122

123+
#if defined(IPPROTO_SCTP)
124+
constexpr static_protocol<BOOST_ASIO_OS_DEF(AF_UNSPEC), BOOST_ASIO_OS_DEF(SOCK_SEQPACKET), IPPROTO_SCTP> sctp {};
125+
constexpr static_protocol<BOOST_ASIO_OS_DEF(AF_INET), BOOST_ASIO_OS_DEF(SOCK_SEQPACKET), IPPROTO_SCTP> sctp_v4{};
126+
constexpr static_protocol<BOOST_ASIO_OS_DEF(AF_INET6), BOOST_ASIO_OS_DEF(SOCK_SEQPACKET), IPPROTO_SCTP> sctp_v6{};
127+
#endif
128+
123129
template<protocol_type::family_t Family>
124130
struct make_endpoint_tag {};
125131

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

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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_IOSEQ_PACKET_SOCKET_HPP
9+
#define BOOST_COBALT_IOSEQ_PACKET_SOCKET_HPP
10+
11+
#include <boost/cobalt/io/endpoint.hpp>
12+
#include <boost/cobalt/io/socket.hpp>
13+
14+
#include <boost/asio/generic/datagram_protocol.hpp>
15+
#include <boost/asio/basic_seq_packet_socket.hpp>
16+
17+
namespace boost::cobalt::io
18+
{
19+
20+
struct [[nodiscard]] seq_packet_socket final : socket
21+
{
22+
BOOST_COBALT_IO_DECL seq_packet_socket(const cobalt::executor & executor = this_thread::get_executor());
23+
BOOST_COBALT_IO_DECL seq_packet_socket(seq_packet_socket && lhs);
24+
BOOST_COBALT_IO_DECL seq_packet_socket(native_handle_type h, protocol_type protocol = protocol_type(),
25+
const executor & executor = this_thread::get_executor());
26+
BOOST_COBALT_IO_DECL seq_packet_socket(endpoint ep,
27+
const executor & executor = this_thread::get_executor());
28+
29+
30+
struct [[nodiscard]] send_op final : op<system::error_code, std::size_t>
31+
{
32+
message_flags in_flags;
33+
const_buffer_sequence buffer;
34+
35+
send_op(message_flags in_flags, const_buffer_sequence buffer,
36+
asio::basic_seq_packet_socket<protocol_type, executor> & seq_packet_socket)
37+
: in_flags(in_flags), buffer(buffer), socket_(seq_packet_socket) {}
38+
39+
BOOST_COBALT_IO_DECL
40+
void initiate(completion_handler<system::error_code, std::size_t> handler) final;
41+
private:
42+
asio::basic_seq_packet_socket<protocol_type, executor> & socket_;
43+
};
44+
45+
struct [[nodiscard]] receive_op final : op<system::error_code, std::size_t>
46+
{
47+
message_flags in_flags, *out_flags;
48+
mutable_buffer_sequence buffer;
49+
50+
receive_op(message_flags in_flags, message_flags * out_flags,
51+
mutable_buffer_sequence buffer, asio::basic_seq_packet_socket<protocol_type, executor> & seq_packet_socket)
52+
: in_flags(in_flags), out_flags(out_flags), buffer(buffer), socket_(seq_packet_socket) {}
53+
54+
BOOST_COBALT_IO_DECL
55+
void initiate(completion_handler<system::error_code, std::size_t> handler) final;
56+
private:
57+
asio::basic_seq_packet_socket<protocol_type, executor> & socket_;
58+
};
59+
60+
receive_op receive(message_flags in_flags, message_flags& out_flags, mutable_buffer_sequence buffer)
61+
{
62+
return receive_op{in_flags, &out_flags, buffer, seq_packet_socket_};
63+
}
64+
65+
send_op send(message_flags in_flags, const_buffer_sequence buffer)
66+
{
67+
return send_op{in_flags, buffer, seq_packet_socket_};
68+
}
69+
receive_op receive(message_flags in_flags, mutable_buffer_sequence buffer)
70+
{
71+
return receive_op{in_flags, nullptr, buffer, seq_packet_socket_};
72+
}
73+
74+
public:
75+
BOOST_COBALT_IO_DECL void adopt_endpoint_(endpoint & ep) override;
76+
77+
asio::basic_seq_packet_socket<protocol_type, executor> seq_packet_socket_;
78+
};
79+
80+
81+
inline system::result<std::pair<seq_packet_socket, seq_packet_socket>> make_pair(decltype(local_seqpacket) protocol)
82+
{
83+
std::pair<seq_packet_socket, seq_packet_socket> res;
84+
auto c = connect_pair(protocol, res.first, res.second);
85+
if (c)
86+
return res;
87+
else
88+
return c.error();
89+
}
90+
91+
}
92+
93+
#endif //BOOST_COBALT_IOSEQ_PACKET_SOCKET_HPP

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
66
//
77

8-
#ifndef BOOST_COBALT_EXPERIMENTAL_IO_SOCKET_HPP
9-
#define BOOST_COBALT_EXPERIMENTAL_IO_SOCKET_HPP
8+
#ifndef BOOST_COBALT_IOSOCKET_HPP
9+
#define BOOST_COBALT_IOSOCKET_HPP
1010

1111
#include <boost/cobalt/io/endpoint.hpp>
1212
#include <boost/cobalt/io/ops.hpp>
@@ -155,4 +155,4 @@ BOOST_COBALT_IO_DECL system::result<void> connect_pair(protocol_type protocol, s
155155

156156
}
157157

158-
#endif //BOOST_COBALT_EXPERIMENTAL_IO_SOCKET_HPP
158+
#endif //BOOST_COBALT_IOSOCKET_HPP

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

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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_IO_STREAM_SOCKET_HPP
9+
#define BOOST_COBALT_IO_STREAM_SOCKET_HPP
10+
11+
#include <boost/cobalt/io/endpoint.hpp>
12+
#include <boost/cobalt/io/socket.hpp>
13+
#include <boost/cobalt/io/stream.hpp>
14+
15+
#include <boost/asio/generic/datagram_protocol.hpp>
16+
#include <boost/asio/basic_stream_socket.hpp>
17+
18+
namespace boost::cobalt::io
19+
{
20+
21+
struct [[nodiscard]] stream_socket final : socket, stream
22+
{
23+
24+
BOOST_COBALT_IO_DECL stream_socket(const cobalt::executor & executor = this_thread::get_executor());
25+
BOOST_COBALT_IO_DECL stream_socket(stream_socket && lhs);
26+
BOOST_COBALT_IO_DECL stream_socket(native_handle_type h, protocol_type protocol = protocol_type(),
27+
const cobalt::executor & executor = this_thread::get_executor());
28+
BOOST_COBALT_IO_DECL stream_socket(endpoint ep,
29+
const cobalt::executor & executor = this_thread::get_executor());
30+
31+
write_op write_some(const_buffer_sequence buffer) override
32+
{
33+
return {buffer, this, initiate_write_some_};
34+
}
35+
read_op read_some(mutable_buffer_sequence buffer) override
36+
{
37+
return {buffer, this, initiate_read_some_};
38+
}
39+
40+
public:
41+
BOOST_COBALT_IO_DECL void adopt_endpoint_(endpoint & ep) override;
42+
43+
BOOST_COBALT_IO_DECL static void initiate_read_some_ (void *, mutable_buffer_sequence, boost::cobalt::completion_handler<system::error_code, std::size_t>);
44+
BOOST_COBALT_IO_DECL static void initiate_write_some_(void *, const_buffer_sequence, boost::cobalt::completion_handler<system::error_code, std::size_t>);
45+
46+
asio::basic_stream_socket<protocol_type, executor> stream_socket_;
47+
};
48+
49+
50+
inline system::result<std::pair<stream_socket, stream_socket>> make_pair(decltype(local_stream) protocol)
51+
{
52+
std::pair<stream_socket, stream_socket> res;
53+
auto c = connect_pair(protocol, res.first, res.second);
54+
if (c)
55+
return res;
56+
else
57+
return c.error();
58+
}
59+
60+
}
61+
62+
#endif //BOOST_COBALT_IOSTREAM_SOCKET_HPP

0 commit comments

Comments
 (0)