11 #ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP 12 #define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 20 #if defined(ASIO_HAS_IOCP) 52 template <
typename Protocol>
53 class win_iocp_socket_service :
public win_iocp_socket_service_base
57 typedef Protocol protocol_type;
60 typedef typename Protocol::endpoint endpoint_type;
63 class native_handle_type
68 have_remote_endpoint_(false)
72 native_handle_type(
socket_type s,
const endpoint_type& ep)
74 have_remote_endpoint_(true),
82 have_remote_endpoint_ =
false;
83 remote_endpoint_ = endpoint_type();
91 bool have_remote_endpoint()
const 93 return have_remote_endpoint_;
96 endpoint_type remote_endpoint()
const 98 return remote_endpoint_;
103 bool have_remote_endpoint_;
104 endpoint_type remote_endpoint_;
108 struct implementation_type :
109 win_iocp_socket_service_base::base_implementation_type
112 implementation_type()
113 : protocol_(endpoint_type().protocol()),
114 have_remote_endpoint_(false),
120 protocol_type protocol_;
123 bool have_remote_endpoint_;
126 endpoint_type remote_endpoint_;
131 : win_iocp_socket_service_base(io_service)
136 void move_construct(implementation_type& impl,
137 implementation_type& other_impl)
139 this->base_move_construct(impl, other_impl);
141 impl.protocol_ = other_impl.protocol_;
142 other_impl.protocol_ = endpoint_type().protocol();
144 impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_;
145 other_impl.have_remote_endpoint_ =
false;
147 impl.remote_endpoint_ = other_impl.remote_endpoint_;
148 other_impl.remote_endpoint_ = endpoint_type();
152 void move_assign(implementation_type& impl,
153 win_iocp_socket_service_base& other_service,
154 implementation_type& other_impl)
156 this->base_move_assign(impl, other_service, other_impl);
158 impl.protocol_ = other_impl.protocol_;
159 other_impl.protocol_ = endpoint_type().protocol();
161 impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_;
162 other_impl.have_remote_endpoint_ =
false;
164 impl.remote_endpoint_ = other_impl.remote_endpoint_;
165 other_impl.remote_endpoint_ = endpoint_type();
169 template <
typename Protocol1>
170 void converting_move_construct(implementation_type& impl,
171 typename win_iocp_socket_service<
172 Protocol1>::implementation_type& other_impl)
174 this->base_move_construct(impl, other_impl);
176 impl.protocol_ = protocol_type(other_impl.protocol_);
177 other_impl.protocol_ =
typename Protocol1::endpoint().protocol();
179 impl.have_remote_endpoint_ = other_impl.have_remote_endpoint_;
180 other_impl.have_remote_endpoint_ =
false;
182 impl.remote_endpoint_ = other_impl.remote_endpoint_;
183 other_impl.remote_endpoint_ =
typename Protocol1::endpoint();
190 if (!do_open(impl, protocol.family(),
191 protocol.type(), protocol.protocol(), ec))
193 impl.protocol_ = protocol;
194 impl.have_remote_endpoint_ =
false;
195 impl.remote_endpoint_ = endpoint_type();
202 const protocol_type& protocol,
const native_handle_type& native_socket,
205 if (!do_assign(impl, protocol.type(), native_socket, ec))
207 impl.protocol_ = protocol;
208 impl.have_remote_endpoint_ = native_socket.have_remote_endpoint();
209 impl.remote_endpoint_ = native_socket.remote_endpoint();
215 native_handle_type native_handle(implementation_type& impl)
217 if (impl.have_remote_endpoint_)
218 return native_handle_type(impl.socket_, impl.remote_endpoint_);
219 return native_handle_type(impl.socket_);
231 template <
typename Option>
236 option.level(impl.protocol_), option.name(impl.protocol_),
237 option.data(impl.protocol_), option.size(impl.protocol_), ec);
242 template <
typename Option>
246 std::size_t size = option.size(impl.protocol_);
248 option.level(impl.protocol_), option.name(impl.protocol_),
249 option.data(impl.protocol_), &size, ec);
251 option.resize(impl.protocol_, size);
256 endpoint_type local_endpoint(
const implementation_type& impl,
259 endpoint_type endpoint;
260 std::size_t addr_len = endpoint.capacity();
262 return endpoint_type();
263 endpoint.resize(addr_len);
268 endpoint_type remote_endpoint(
const implementation_type& impl,
271 endpoint_type endpoint = impl.remote_endpoint_;
272 std::size_t addr_len = endpoint.capacity();
274 &addr_len, impl.have_remote_endpoint_, ec))
275 return endpoint_type();
276 endpoint.resize(addr_len);
282 template <
typename ConstBufferSequence>
283 size_t send_to(implementation_type& impl,
const ConstBufferSequence&
buffers,
288 ConstBufferSequence> bufs(buffers);
291 bufs.buffers(), bufs.count(), flags,
292 destination.data(), destination.size(), ec);
296 size_t send_to(implementation_type& impl,
const null_buffers&,
308 template <
typename ConstBufferSequence,
typename Handler>
309 void async_send_to(implementation_type& impl,
310 const ConstBufferSequence& buffers,
const endpoint_type& destination,
314 typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op;
315 typename op::ptr p = { asio::detail::addressof(handler),
317 sizeof(op), handler), 0 };
318 p.p =
new (p.v) op(impl.cancel_token_, buffers, handler);
322 buffer_sequence_adapter<asio::const_buffer,
323 ConstBufferSequence> bufs(buffers);
325 start_send_to_op(impl, bufs.buffers(), bufs.count(),
326 destination.data(),
static_cast<int>(destination.size()),
332 template <
typename Handler>
333 void async_send_to(implementation_type& impl,
const null_buffers&,
337 typedef win_iocp_null_buffers_op<Handler> op;
338 typename op::ptr p = { asio::detail::addressof(handler),
340 sizeof(op), handler), 0 };
341 p.p =
new (p.v) op(impl.cancel_token_, handler);
344 &impl,
"async_send_to(null_buffers)"));
346 start_reactor_op(impl, reactor::write_op, p.p);
352 template <
typename MutableBufferSequence>
353 size_t receive_from(implementation_type& impl,
354 const MutableBufferSequence& buffers,
359 MutableBufferSequence> bufs(buffers);
361 std::size_t addr_len = sender_endpoint.capacity();
363 impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
364 flags, sender_endpoint.data(), &addr_len, ec);
367 sender_endpoint.resize(addr_len);
373 size_t receive_from(implementation_type& impl,
374 const null_buffers&, endpoint_type& sender_endpoint,
381 sender_endpoint = endpoint_type();
389 template <
typename MutableBufferSequence,
typename Handler>
390 void async_receive_from(implementation_type& impl,
391 const MutableBufferSequence& buffers, endpoint_type& sender_endp,
395 typedef win_iocp_socket_recvfrom_op<
396 MutableBufferSequence, endpoint_type, Handler> op;
397 typename op::ptr p = { asio::detail::addressof(handler),
399 sizeof(op), handler), 0 };
400 p.p =
new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler);
404 buffer_sequence_adapter<asio::mutable_buffer,
405 MutableBufferSequence> bufs(buffers);
407 start_receive_from_op(impl, bufs.buffers(), bufs.count(),
408 sender_endp.data(), flags, &p.p->endpoint_size(), p.p);
413 template <
typename Handler>
414 void async_receive_from(implementation_type& impl,
415 const null_buffers&, endpoint_type& sender_endpoint,
419 typedef win_iocp_null_buffers_op<Handler> op;
420 typename op::ptr p = { asio::detail::addressof(handler),
422 sizeof(op), handler), 0 };
423 p.p =
new (p.v) op(impl.cancel_token_, handler);
426 "async_receive_from(null_buffers)"));
429 sender_endpoint = endpoint_type();
431 start_null_buffers_receive_op(impl, flags, p.p);
436 template <
typename Socket>
447 std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
449 impl.state_, peer_endpoint ? peer_endpoint->data() : 0,
450 peer_endpoint ? &addr_len : 0, ec));
456 peer_endpoint->resize(addr_len);
457 if (!peer.assign(impl.protocol_, new_socket.get(), ec))
458 new_socket.release();
466 template <
typename Socket,
typename Handler>
467 void async_accept(implementation_type& impl, Socket& peer,
468 endpoint_type* peer_endpoint, Handler& handler)
471 typedef win_iocp_socket_accept_op<Socket, protocol_type, Handler> op;
472 typename op::ptr p = { asio::detail::addressof(handler),
474 sizeof(op), handler), 0 };
477 p.p =
new (p.v) op(*
this, impl.socket_, peer, impl.protocol_,
478 peer_endpoint, enable_connection_aborted, handler);
482 start_accept_op(impl, peer.is_open(), p.p->new_socket(),
483 impl.protocol_.family(), impl.protocol_.type(),
484 impl.protocol_.protocol(), p.p->output_buffer(),
485 p.p->address_length(), p.p);
494 peer_endpoint.data(), peer_endpoint.size(), ec);
499 template <
typename Handler>
500 void async_connect(implementation_type& impl,
501 const endpoint_type& peer_endpoint, Handler& handler)
504 typedef win_iocp_socket_connect_op<Handler> op;
505 typename op::ptr p = { asio::detail::addressof(handler),
507 sizeof(op), handler), 0 };
508 p.p =
new (p.v) op(impl.socket_, handler);
512 start_connect_op(impl, impl.protocol_.family(), impl.protocol_.type(),
513 peer_endpoint.data(),
static_cast<int>(peer_endpoint.size()), p.p);
523 #endif // defined(ASIO_HAS_IOCP) 525 #endif // ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP int message_flags
Bitmask type for flags that can be passed to send and receive operations.
Provides core I/O functionality.
Holds a buffer that cannot be modified.
int getsockopt(socket_type s, state_type state, int level, int optname, void *optval, size_t *optlen, asio::error_code &ec)
int getsockname(socket_type s, socket_addr_type *addr, std::size_t *addrlen, asio::error_code &ec)
Iterator connect(basic_socket< Protocol, SocketService > &s, Iterator begin)
Establishes a socket connection by trying each endpoint in a sequence.
int poll_read(socket_type s, state_type state, asio::error_code &ec)
size_t sync_sendto(socket_type s, state_type state, const buf *bufs, size_t count, int flags, const socket_addr_type *addr, std::size_t addrlen, asio::error_code &ec)
const MutableBufferSequence & buffers
int setsockopt(socket_type s, state_type &state, int level, int optname, const void *optval, std::size_t optlen, asio::error_code &ec)
Holds a buffer that can be modified.
int poll_write(socket_type s, state_type state, asio::error_code &ec)
int bind(socket_type s, const socket_addr_type *addr, std::size_t addrlen, asio::error_code &ec)
Class to represent an error code value.
socket_type accept(socket_type s, socket_addr_type *addr, std::size_t *addrlen, asio::error_code &ec)
void sync_connect(socket_type s, const socket_addr_type *addr, std::size_t addrlen, asio::error_code &ec)
void * allocate(std::size_t s, Handler &h)
int getpeername(socket_type s, socket_addr_type *addr, std::size_t *addrlen, bool cached, asio::error_code &ec)
size_t sync_recvfrom(socket_type s, state_type state, buf *bufs, size_t count, int flags, socket_addr_type *addr, std::size_t *addrlen, asio::error_code &ec)
ASIO_DECL int open(const char *path, int flags, asio::error_code &ec)
#define ASIO_HANDLER_CREATION(args)
socket_type sync_accept(socket_type s, state_type state, socket_addr_type *addr, std::size_t *addrlen, asio::error_code &ec)