Skip to content
Navigation Menu
{{ message }}
forked from lewissbaker/cppcoro
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocket.hpp
More file actions
268 lines (232 loc) · 8.87 KB
/
Copy pathsocket.hpp
File metadata and controls
268 lines (232 loc) · 8.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Lewis Baker
// Licenced under MIT license. See LICENSE.txt for details.
///////////////////////////////////////////////////////////////////////////////
#ifndef CPPCORO_NET_SOCKET_HPP_INCLUDED
#define CPPCORO_NET_SOCKET_HPP_INCLUDED
#include <cppcoro/config.hpp>
#include <cppcoro/net/ip_endpoint.hpp>
#include <cppcoro/net/socket_accept_operation.hpp>
#include <cppcoro/net/socket_connect_operation.hpp>
#include <cppcoro/net/socket_disconnect_operation.hpp>
#include <cppcoro/net/socket_recv_operation.hpp>
#include <cppcoro/net/socket_recv_from_operation.hpp>
#include <cppcoro/net/socket_send_operation.hpp>
#include <cppcoro/net/socket_send_to_operation.hpp>
#include <cppcoro/cancellation_token.hpp>
#if CPPCORO_OS_WINNT
# include <cppcoro/detail/win32.hpp>
#endif
namespace cppcoro
{
class io_service;
namespace net
{
class socket
{
public:
/// Create a socket that can be used to communicate using TCP/IPv4 protocol.
///
/// \param ioSvc
/// The I/O service the socket will use for dispatching I/O completion events.
///
/// \return
/// The newly created socket.
///
/// \throws std::system_error
/// If the socket could not be created for some reason.
static socket create_tcpv4(io_service& ioSvc);
/// Create a socket that can be used to communicate using TCP/IPv6 protocol.
///
/// \param ioSvc
/// The I/O service the socket will use for dispatching I/O completion events.
///
/// \return
/// The newly created socket.
///
/// \throws std::system_error
/// If the socket could not be created for some reason.
static socket create_tcpv6(io_service& ioSvc);
/// Create a socket that can be used to communicate using UDP/IPv4 protocol.
///
/// \param ioSvc
/// The I/O service the socket will use for dispatching I/O completion events.
///
/// \return
/// The newly created socket.
///
/// \throws std::system_error
/// If the socket could not be created for some reason.
static socket create_udpv4(io_service& ioSvc);
/// Create a socket that can be used to communicate using UDP/IPv6 protocol.
///
/// \param ioSvc
/// The I/O service the socket will use for dispatching I/O completion events.
///
/// \return
/// The newly created socket.
///
/// \throws std::system_error
/// If the socket could not be created for some reason.
static socket create_udpv6(io_service& ioSvc);
socket(socket&& other) noexcept;
/// Closes the socket, releasing any associated resources.
///
/// If the socket still has an open connection then the connection will be
/// reset. The destructor will not block waiting for queueud data to be sent.
/// If you need to ensure that queued data is delivered then you must call
/// disconnect() and wait until the disconnect operation completes.
~socket();
socket& operator=(socket&& other) noexcept;
#if CPPCORO_OS_WINNT
/// Get the Win32 socket handle assocaited with this socket.
cppcoro::detail::win32::socket_t native_handle() noexcept { return m_handle; }
/// Query whether I/O operations that complete synchronously will skip posting
/// an I/O completion event to the I/O completion port.
///
/// The operation class implementations can use this to determine whether or not
/// it should immediately resume the coroutine on the current thread upon an
/// operation completing synchronously or whether it should suspend the coroutine
/// and wait until the I/O completion event is dispatched to an I/O thread.
bool skip_completion_on_success() noexcept { return m_skipCompletionOnSuccess; }
#endif
/// Get the address and port of the local end-point.
///
/// If the socket is not bound then this will be the unspecified end-point
/// of the socket's associated address-family.
const ip_endpoint& local_endpoint() const noexcept { return m_localEndPoint; }
/// Get the address and port of the remote end-point.
///
/// If the socket is not in the connected state then this will be the unspecified
/// end-point of the socket's associated address-family.
const ip_endpoint& remote_endpoint() const noexcept { return m_remoteEndPoint; }
/// Bind the local end of this socket to the specified local end-point.
///
/// \param localEndPoint
/// The end-point to bind to.
/// This can be either an unspecified address (in which case it binds to all available
/// interfaces) and/or an unspecified port (in which case a random port is allocated).
///
/// \throws std::system_error
/// If the socket could not be bound for some reason.
void bind(const ip_endpoint& localEndPoint);
/// Put the socket into a passive listening state that will start acknowledging
/// and queueing up new connections ready to be accepted by a call to 'accept()'.
///
/// The backlog of connections ready to be accepted will be set to some default
/// suitable large value, depending on the network provider. If you need more
/// control over the size of the queue then use the overload of listen()
/// that accepts a 'backlog' parameter.
///
/// \throws std::system_error
/// If the socket could not be placed into a listening mode.
void listen();
/// Put the socket into a passive listening state that will start acknowledging
/// and queueing up new connections ready to be accepted by a call to 'accept()'.
///
/// \param backlog
/// The maximum number of pending connections to allow in the queue of ready-to-accept
/// connections.
///
/// \throws std::system_error
/// If the socket could not be placed into a listening mode.
void listen(std::uint32_t backlog);
/// Connect the socket to the specified remote end-point.
///
/// The socket must be in a bound but unconnected state prior to this call.
///
/// \param remoteEndPoint
/// The IP address and port-number to connect to.
///
/// \return
/// An awaitable object that must be co_await'ed to perform the async connect
/// operation. The result of the co_await expression is type void.
[[nodiscard]]
socket_connect_operation connect(const ip_endpoint& remoteEndPoint) noexcept;
/// Connect to the specified remote end-point.
///
/// \param remoteEndPoint
/// The IP address and port of the remote end-point to connect to.
///
/// \param ct
/// A cancellation token that can be used to communicate a request to
/// later cancel the operation. If the operation is successfully
/// cancelled then it will complete by throwing a cppcoro::operation_cancelled
/// exception.
///
/// \return
/// An awaitable object that will start the connect operation when co_await'ed
/// and will suspend the coroutine, resuming it when the operation completes.
/// The result of the co_await expression has type 'void'.
[[nodiscard]]
socket_connect_operation_cancellable connect(
const ip_endpoint& remoteEndPoint,
cancellation_token ct) noexcept;
[[nodiscard]]
socket_accept_operation accept(socket& acceptingSocket) noexcept;
[[nodiscard]]
socket_accept_operation_cancellable accept(
socket& acceptingSocket,
cancellation_token ct) noexcept;
[[nodiscard]]
socket_disconnect_operation disconnect() noexcept;
[[nodiscard]]
socket_disconnect_operation_cancellable disconnect(cancellation_token ct) noexcept;
[[nodiscard]]
socket_send_operation send(
const void* buffer,
std::size_t size) noexcept;
[[nodiscard]]
socket_send_operation_cancellable send(
const void* buffer,
std::size_t size,
cancellation_token ct) noexcept;
[[nodiscard]]
socket_recv_operation recv(
void* buffer,
std::size_t size) noexcept;
[[nodiscard]]
socket_recv_operation_cancellable recv(
void* buffer,
std::size_t size,
cancellation_token ct) noexcept;
[[nodiscard]]
socket_recv_from_operation recv_from(
void* buffer,
std::size_t size) noexcept;
[[nodiscard]]
socket_recv_from_operation_cancellable recv_from(
void* buffer,
std::size_t size,
cancellation_token ct) noexcept;
[[nodiscard]]
socket_send_to_operation send_to(
const ip_endpoint& destination,
const void* buffer,
std::size_t size) noexcept;
[[nodiscard]]
socket_send_to_operation_cancellable send_to(
const ip_endpoint& destination,
const void* buffer,
std::size_t size,
cancellation_token ct) noexcept;
void close_send();
void close_recv();
private:
friend class socket_accept_operation_impl;
friend class socket_connect_operation_impl;
#if CPPCORO_OS_WINNT
explicit socket(
cppcoro::detail::win32::socket_t handle,
bool skipCompletionOnSuccess) noexcept;
#endif
#if CPPCORO_OS_WINNT
cppcoro::detail::win32::socket_t m_handle;
bool m_skipCompletionOnSuccess;
#endif
ip_endpoint m_localEndPoint;
ip_endpoint m_remoteEndPoint;
};
}
}
#endif
You can’t perform that action at this time.
