11 #ifndef ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP 12 #define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 #include "asio/detail/config.hpp" 20 #if !defined(ASIO_HAS_IOCP) 22 #include "asio/buffer.hpp" 23 #include "asio/error.hpp" 24 #include "asio/execution_context.hpp" 25 #include "asio/socket_base.hpp" 26 #include "asio/detail/buffer_sequence_adapter.hpp" 27 #include "asio/detail/memory.hpp" 28 #include "asio/detail/noncopyable.hpp" 29 #include "asio/detail/reactive_null_buffers_op.hpp" 30 #include "asio/detail/reactive_socket_accept_op.hpp" 31 #include "asio/detail/reactive_socket_connect_op.hpp" 32 #include "asio/detail/reactive_socket_recvfrom_op.hpp" 33 #include "asio/detail/reactive_socket_sendto_op.hpp" 34 #include "asio/detail/reactive_socket_service_base.hpp" 35 #include "asio/detail/reactor.hpp" 36 #include "asio/detail/reactor_op.hpp" 37 #include "asio/detail/socket_holder.hpp" 38 #include "asio/detail/socket_ops.hpp" 39 #include "asio/detail/socket_types.hpp" 41 #include "asio/detail/push_options.hpp" 46 template <
typename Protocol>
53 typedef Protocol protocol_type;
56 typedef typename Protocol::endpoint endpoint_type;
59 typedef socket_type native_handle_type;
67 : protocol_(endpoint_type().protocol())
72 protocol_type protocol_;
86 this->base_shutdown();
93 this->base_move_construct(impl, other_impl);
95 impl.protocol_ = other_impl.protocol_;
96 other_impl.protocol_ = endpoint_type().protocol();
104 this->base_move_assign(impl, other_service, other_impl);
106 impl.protocol_ = other_impl.protocol_;
107 other_impl.protocol_ = endpoint_type().protocol();
111 template <
typename Protocol1>
117 this->base_move_construct(impl, other_impl);
119 impl.protocol_ = protocol_type(other_impl.protocol_);
120 other_impl.protocol_ =
typename Protocol1::endpoint().protocol();
127 if (!do_open(impl, protocol.family(),
128 protocol.type(), protocol.protocol(), ec))
129 impl.protocol_ = protocol;
135 const protocol_type& protocol,
const native_handle_type& native_socket,
138 if (!do_assign(impl, protocol.type(), native_socket, ec))
139 impl.protocol_ = protocol;
153 socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);
158 template <
typename Option>
162 socket_ops::setsockopt(impl.socket_, impl.state_,
163 option.level(impl.protocol_), option.name(impl.protocol_),
164 option.data(impl.protocol_), option.size(impl.protocol_), ec);
169 template <
typename Option>
173 std::size_t size = option.size(impl.protocol_);
174 socket_ops::getsockopt(impl.socket_, impl.state_,
175 option.level(impl.protocol_), option.name(impl.protocol_),
176 option.data(impl.protocol_), &size, ec);
178 option.resize(impl.protocol_, size);
186 endpoint_type endpoint;
187 std::size_t addr_len = endpoint.capacity();
188 if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
189 return endpoint_type();
190 endpoint.resize(addr_len);
198 endpoint_type endpoint;
199 std::size_t addr_len = endpoint.capacity();
200 if (socket_ops::getpeername(impl.socket_,
201 endpoint.data(), &addr_len,
false, ec))
202 return endpoint_type();
203 endpoint.resize(addr_len);
211 socket_ops::shutdown(impl.socket_, what, ec);
217 template <
typename ConstBufferSequence>
223 ConstBufferSequence> bufs_type;
225 if (bufs_type::is_single_buffer)
227 return socket_ops::sync_sendto1(impl.socket_, impl.state_,
228 bufs_type::first(buffers).data(),
229 bufs_type::first(buffers).size(), flags,
230 destination.data(), destination.size(), ec);
234 bufs_type bufs(buffers);
235 return socket_ops::sync_sendto(impl.socket_, impl.state_,
236 bufs.buffers(), bufs.count(), flags,
237 destination.data(), destination.size(), ec);
247 socket_ops::poll_write(impl.socket_, impl.state_, -1, ec);
254 template <
typename ConstBufferSequence,
typename Handler,
typename IoExecutor>
256 const ConstBufferSequence& buffers,
258 Handler& handler,
const IoExecutor& io_ex)
260 bool is_continuation =
261 asio_handler_cont_helpers::is_continuation(handler);
265 endpoint_type, Handler, IoExecutor> op;
266 typename op::ptr p = { asio::detail::addressof(handler),
267 op::ptr::allocate(handler), 0 };
268 p.p =
new (p.v) op(success_ec_, impl.socket_,
269 buffers, destination, flags, handler, io_ex);
271 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
272 &impl, impl.socket_,
"async_send_to"));
274 start_op(impl, reactor::write_op, p.p, is_continuation,
true,
false);
279 template <
typename Handler,
typename IoExecutor>
282 Handler& handler,
const IoExecutor& io_ex)
284 bool is_continuation =
285 asio_handler_cont_helpers::is_continuation(handler);
289 typename op::ptr p = { asio::detail::addressof(handler),
290 op::ptr::allocate(handler), 0 };
291 p.p =
new (p.v) op(success_ec_, handler, io_ex);
293 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
294 &impl, impl.socket_,
"async_send_to(null_buffers)"));
296 start_op(impl, reactor::write_op, p.p, is_continuation,
false,
false);
302 template <
typename MutableBufferSequence>
304 const MutableBufferSequence& buffers,
309 MutableBufferSequence> bufs_type;
311 std::size_t addr_len = sender_endpoint.capacity();
312 std::size_t bytes_recvd;
313 if (bufs_type::is_single_buffer)
315 bytes_recvd = socket_ops::sync_recvfrom1(impl.socket_,
316 impl.state_, bufs_type::first(buffers).data(),
317 bufs_type::first(buffers).size(), flags,
318 sender_endpoint.data(), &addr_len, ec);
322 bufs_type bufs(buffers);
323 bytes_recvd = socket_ops::sync_recvfrom(
324 impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
325 flags, sender_endpoint.data(), &addr_len, ec);
329 sender_endpoint.resize(addr_len);
340 socket_ops::poll_read(impl.socket_, impl.state_, -1, ec);
343 sender_endpoint = endpoint_type();
351 template <
typename MutableBufferSequence,
352 typename Handler,
typename IoExecutor>
354 const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
356 const IoExecutor& io_ex)
358 bool is_continuation =
359 asio_handler_cont_helpers::is_continuation(handler);
363 endpoint_type, Handler, IoExecutor> op;
364 typename op::ptr p = { asio::detail::addressof(handler),
365 op::ptr::allocate(handler), 0 };
366 int protocol = impl.protocol_.type();
367 p.p =
new (p.v) op(success_ec_, impl.socket_, protocol,
368 buffers, sender_endpoint, flags, handler, io_ex);
370 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
371 &impl, impl.socket_,
"async_receive_from"));
374 (flags & socket_base::message_out_of_band)
375 ? reactor::except_op : reactor::read_op,
376 p.p, is_continuation,
true,
false);
381 template <
typename Handler,
typename IoExecutor>
384 Handler& handler,
const IoExecutor& io_ex)
386 bool is_continuation =
387 asio_handler_cont_helpers::is_continuation(handler);
391 typename op::ptr p = { asio::detail::addressof(handler),
392 op::ptr::allocate(handler), 0 };
393 p.p =
new (p.v) op(success_ec_, handler, io_ex);
395 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
396 &impl, impl.socket_,
"async_receive_from(null_buffers)"));
399 sender_endpoint = endpoint_type();
402 (flags & socket_base::message_out_of_band)
403 ? reactor::except_op : reactor::read_op,
404 p.p, is_continuation,
false,
false);
409 template <
typename Socket>
416 ec = asio::error::already_open;
420 std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
421 socket_holder new_socket(socket_ops::sync_accept(impl.socket_,
422 impl.state_, peer_endpoint ? peer_endpoint->data() : 0,
423 peer_endpoint ? &addr_len : 0, ec));
426 if (new_socket.get() != invalid_socket)
429 peer_endpoint->resize(addr_len);
430 peer.assign(impl.protocol_, new_socket.get(), ec);
432 new_socket.release();
440 template <
typename Socket,
typename Handler,
typename IoExecutor>
442 endpoint_type* peer_endpoint, Handler& handler,
const IoExecutor& io_ex)
444 bool is_continuation =
445 asio_handler_cont_helpers::is_continuation(handler);
449 typename op::ptr p = { asio::detail::addressof(handler),
450 op::ptr::allocate(handler), 0 };
451 p.p =
new (p.v) op(success_ec_, impl.socket_, impl.state_,
452 peer, impl.protocol_, peer_endpoint, handler, io_ex);
454 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
455 &impl, impl.socket_,
"async_accept"));
457 start_accept_op(impl, p.p, is_continuation, peer.is_open());
461 #if defined(ASIO_HAS_MOVE) 464 template <
typename PeerIoExecutor,
typename Handler,
typename IoExecutor>
466 const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint,
467 Handler& handler,
const IoExecutor& io_ex)
469 bool is_continuation =
470 asio_handler_cont_helpers::is_continuation(handler);
473 typedef reactive_socket_move_accept_op<Protocol,
474 PeerIoExecutor, Handler, IoExecutor> op;
475 typename op::ptr p = { asio::detail::addressof(handler),
476 op::ptr::allocate(handler), 0 };
477 p.p =
new (p.v) op(success_ec_, peer_io_ex, impl.socket_,
478 impl.state_, impl.protocol_, peer_endpoint, handler, io_ex);
480 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
481 &impl, impl.socket_,
"async_accept"));
483 start_accept_op(impl, p.p, is_continuation,
false);
486 #endif // defined(ASIO_HAS_MOVE) 492 socket_ops::sync_connect(impl.socket_,
493 peer_endpoint.data(), peer_endpoint.size(), ec);
498 template <
typename Handler,
typename IoExecutor>
500 const endpoint_type& peer_endpoint,
501 Handler& handler,
const IoExecutor& io_ex)
503 bool is_continuation =
504 asio_handler_cont_helpers::is_continuation(handler);
508 typename op::ptr p = { asio::detail::addressof(handler),
509 op::ptr::allocate(handler), 0 };
510 p.p =
new (p.v) op(success_ec_, impl.socket_, handler, io_ex);
512 ASIO_HANDLER_CREATION((reactor_.context(), *p.p,
"socket",
513 &impl, impl.socket_,
"async_connect"));
515 start_connect_op(impl, p.p, is_continuation,
516 peer_endpoint.data(), peer_endpoint.size());
524 #include "asio/detail/pop_options.hpp" 526 #endif // !defined(ASIO_HAS_IOCP) 528 #endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP Definition: reactive_socket_connect_op.hpp:62
int message_flags
Bitmask type for flags that can be passed to send and receive operations.
Definition: socket_base.hpp:53
Holds a buffer that cannot be modified.
Definition: buffer.hpp:226
Definition: reactive_socket_service_base.hpp:52
Definition: execution_context.hpp:386
A context for function object execution.
Definition: execution_context.hpp:105
Definition: reactive_socket_recvfrom_op.hpp:98
void shutdown()
Destroy all user-defined handler objects owned by the service.
Definition: reactive_socket_service.hpp:84
Definition: buffer_sequence_adapter.hpp:103
Holds a buffer that can be modified.
Definition: buffer.hpp:92
shutdown_type
Different ways a socket may be shutdown.
Definition: socket_base.hpp:34
Protocol::endpoint connect(basic_socket< Protocol, Executor > &s, const EndpointSequence &endpoints, typename enable_if< is_endpoint_sequence< EndpointSequence >::value >::type *=0)
Establishes a socket connection by trying each endpoint in a sequence.
Definition: connect.hpp:106
Class to represent an error code value.
Definition: error_code.hpp:80
Definition: reactive_socket_service.hpp:62
Definition: reactive_null_buffers_op.hpp:33
Definition: reactive_socket_service.hpp:47
execution_context & context()
Get the context object that owns the service.
Definition: execution_context.hpp:100
(Deprecated: Use the socket/descriptor wait() and async_wait() member functions.) An implementation o...
Definition: buffer.hpp:354
Definition: socket_holder.hpp:28
Definition: reactive_socket_accept_op.hpp:94
Definition: reactive_socket_service_base.hpp:45
Definition: any_io_executor.hpp:28
Definition: reactive_socket_sendto_op.hpp:92