Clementine
basic_stream_socket.hpp
1 //
2 // basic_stream_socket.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_BASIC_STREAM_SOCKET_HPP
12 #define ASIO_BASIC_STREAM_SOCKET_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include <cstddef>
20 #include "asio/async_result.hpp"
21 #include "asio/basic_socket.hpp"
22 #include "asio/detail/handler_type_requirements.hpp"
23 #include "asio/detail/non_const_lvalue.hpp"
24 #include "asio/detail/throw_error.hpp"
25 #include "asio/error.hpp"
26 
27 #include "asio/detail/push_options.hpp"
28 
29 namespace asio {
30 
31 #if !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
32 #define ASIO_BASIC_STREAM_SOCKET_FWD_DECL
33 
34 // Forward declaration with defaulted arguments.
35 template <typename Protocol, typename Executor = any_io_executor>
37 
38 #endif // !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
39 
41 
52 template <typename Protocol, typename Executor>
54  : public basic_socket<Protocol, Executor>
55 {
56 public:
58  typedef Executor executor_type;
59 
61  template <typename Executor1>
63  {
66  };
67 
69 #if defined(GENERATING_DOCUMENTATION)
70  typedef implementation_defined native_handle_type;
71 #else
72  typedef typename basic_socket<Protocol,
74 #endif
75 
77  typedef Protocol protocol_type;
78 
80  typedef typename Protocol::endpoint endpoint_type;
81 
83 
91  explicit basic_stream_socket(const executor_type& ex)
92  : basic_socket<Protocol, Executor>(ex)
93  {
94  }
95 
97 
106  template <typename ExecutionContext>
107  explicit basic_stream_socket(ExecutionContext& context,
108  typename enable_if<
109  is_convertible<ExecutionContext&, execution_context&>::value
110  >::type* = 0)
111  : basic_socket<Protocol, Executor>(context)
112  {
113  }
114 
116 
127  basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
128  : basic_socket<Protocol, Executor>(ex, protocol)
129  {
130  }
131 
133 
145  template <typename ExecutionContext>
146  basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
147  typename enable_if<
148  is_convertible<ExecutionContext&, execution_context&>::value
149  >::type* = 0)
150  : basic_socket<Protocol, Executor>(context, protocol)
151  {
152  }
153 
156 
169  basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
170  : basic_socket<Protocol, Executor>(ex, endpoint)
171  {
172  }
173 
176 
190  template <typename ExecutionContext>
191  basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
192  typename enable_if<
193  is_convertible<ExecutionContext&, execution_context&>::value
194  >::type* = 0)
195  : basic_socket<Protocol, Executor>(context, endpoint)
196  {
197  }
198 
200 
213  basic_stream_socket(const executor_type& ex,
214  const protocol_type& protocol, const native_handle_type& native_socket)
215  : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
216  {
217  }
218 
220 
234  template <typename ExecutionContext>
235  basic_stream_socket(ExecutionContext& context,
236  const protocol_type& protocol, const native_handle_type& native_socket,
237  typename enable_if<
238  is_convertible<ExecutionContext&, execution_context&>::value
239  >::type* = 0)
240  : basic_socket<Protocol, Executor>(context, protocol, native_socket)
241  {
242  }
243 
244 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
245 
258  {
259  }
260 
262 
273  {
275  return *this;
276  }
277 
280 
290  template <typename Protocol1, typename Executor1>
292  typename enable_if<
293  is_convertible<Protocol1, Protocol>::value
294  && is_convertible<Executor1, Executor>::value
295  >::type* = 0)
297  {
298  }
299 
301 
311  template <typename Protocol1, typename Executor1>
312  typename enable_if<
313  is_convertible<Protocol1, Protocol>::value
314  && is_convertible<Executor1, Executor>::value,
317  {
319  return *this;
320  }
321 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
322 
324 
329  {
330  }
331 
333 
357  template <typename ConstBufferSequence>
358  std::size_t send(const ConstBufferSequence& buffers)
359  {
360  asio::error_code ec;
361  std::size_t s = this->impl_.get_service().send(
362  this->impl_.get_implementation(), buffers, 0, ec);
363  asio::detail::throw_error(ec, "send");
364  return s;
365  }
366 
368 
394  template <typename ConstBufferSequence>
395  std::size_t send(const ConstBufferSequence& buffers,
397  {
398  asio::error_code ec;
399  std::size_t s = this->impl_.get_service().send(
400  this->impl_.get_implementation(), buffers, flags, ec);
401  asio::detail::throw_error(ec, "send");
402  return s;
403  }
404 
406 
423  template <typename ConstBufferSequence>
424  std::size_t send(const ConstBufferSequence& buffers,
426  {
427  return this->impl_.get_service().send(
428  this->impl_.get_implementation(), buffers, flags, ec);
429  }
430 
432 
466  template <typename ConstBufferSequence,
467  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
468  std::size_t)) WriteHandler
469  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
470  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
471  void (asio::error_code, std::size_t))
472  async_send(const ConstBufferSequence& buffers,
473  ASIO_MOVE_ARG(WriteHandler) handler
474  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
475  {
476  return async_initiate<WriteHandler,
477  void (asio::error_code, std::size_t)>(
478  initiate_async_send(this), handler,
479  buffers, socket_base::message_flags(0));
480  }
481 
483 
519  template <typename ConstBufferSequence,
520  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
521  std::size_t)) WriteHandler
522  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
523  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
524  void (asio::error_code, std::size_t))
525  async_send(const ConstBufferSequence& buffers,
527  ASIO_MOVE_ARG(WriteHandler) handler
528  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
529  {
530  return async_initiate<WriteHandler,
531  void (asio::error_code, std::size_t)>(
532  initiate_async_send(this), handler, buffers, flags);
533  }
534 
536 
563  template <typename MutableBufferSequence>
564  std::size_t receive(const MutableBufferSequence& buffers)
565  {
566  asio::error_code ec;
567  std::size_t s = this->impl_.get_service().receive(
568  this->impl_.get_implementation(), buffers, 0, ec);
569  asio::detail::throw_error(ec, "receive");
570  return s;
571  }
572 
574 
603  template <typename MutableBufferSequence>
604  std::size_t receive(const MutableBufferSequence& buffers,
606  {
607  asio::error_code ec;
608  std::size_t s = this->impl_.get_service().receive(
609  this->impl_.get_implementation(), buffers, flags, ec);
610  asio::detail::throw_error(ec, "receive");
611  return s;
612  }
613 
615 
632  template <typename MutableBufferSequence>
633  std::size_t receive(const MutableBufferSequence& buffers,
635  {
636  return this->impl_.get_service().receive(
637  this->impl_.get_implementation(), buffers, flags, ec);
638  }
639 
641 
677  template <typename MutableBufferSequence,
678  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
679  std::size_t)) ReadHandler
680  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
681  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
682  void (asio::error_code, std::size_t))
683  async_receive(const MutableBufferSequence& buffers,
684  ASIO_MOVE_ARG(ReadHandler) handler
685  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
686  {
687  return async_initiate<ReadHandler,
688  void (asio::error_code, std::size_t)>(
689  initiate_async_receive(this), handler,
690  buffers, socket_base::message_flags(0));
691  }
692 
694 
732  template <typename MutableBufferSequence,
733  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
734  std::size_t)) ReadHandler
735  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
736  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
737  void (asio::error_code, std::size_t))
738  async_receive(const MutableBufferSequence& buffers,
740  ASIO_MOVE_ARG(ReadHandler) handler
741  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
742  {
743  return async_initiate<ReadHandler,
744  void (asio::error_code, std::size_t)>(
745  initiate_async_receive(this), handler, buffers, flags);
746  }
747 
749 
775  template <typename ConstBufferSequence>
776  std::size_t write_some(const ConstBufferSequence& buffers)
777  {
778  asio::error_code ec;
779  std::size_t s = this->impl_.get_service().send(
780  this->impl_.get_implementation(), buffers, 0, ec);
781  asio::detail::throw_error(ec, "write_some");
782  return s;
783  }
784 
786 
801  template <typename ConstBufferSequence>
802  std::size_t write_some(const ConstBufferSequence& buffers,
803  asio::error_code& ec)
804  {
805  return this->impl_.get_service().send(
806  this->impl_.get_implementation(), buffers, 0, ec);
807  }
808 
810 
844  template <typename ConstBufferSequence,
845  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
846  std::size_t)) WriteHandler
847  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
848  ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
849  void (asio::error_code, std::size_t))
850  async_write_some(const ConstBufferSequence& buffers,
851  ASIO_MOVE_ARG(WriteHandler) handler
852  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
853  {
854  return async_initiate<WriteHandler,
855  void (asio::error_code, std::size_t)>(
856  initiate_async_send(this), handler,
857  buffers, socket_base::message_flags(0));
858  }
859 
861 
888  template <typename MutableBufferSequence>
889  std::size_t read_some(const MutableBufferSequence& buffers)
890  {
891  asio::error_code ec;
892  std::size_t s = this->impl_.get_service().receive(
893  this->impl_.get_implementation(), buffers, 0, ec);
894  asio::detail::throw_error(ec, "read_some");
895  return s;
896  }
897 
899 
915  template <typename MutableBufferSequence>
916  std::size_t read_some(const MutableBufferSequence& buffers,
917  asio::error_code& ec)
918  {
919  return this->impl_.get_service().receive(
920  this->impl_.get_implementation(), buffers, 0, ec);
921  }
922 
924 
959  template <typename MutableBufferSequence,
960  ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,
961  std::size_t)) ReadHandler
962  ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
963  ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
964  void (asio::error_code, std::size_t))
965  async_read_some(const MutableBufferSequence& buffers,
966  ASIO_MOVE_ARG(ReadHandler) handler
967  ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
968  {
969  return async_initiate<ReadHandler,
970  void (asio::error_code, std::size_t)>(
971  initiate_async_receive(this), handler,
972  buffers, socket_base::message_flags(0));
973  }
974 
975 private:
976  // Disallow copying and assignment.
977  basic_stream_socket(const basic_stream_socket&) ASIO_DELETED;
978  basic_stream_socket& operator=(const basic_stream_socket&) ASIO_DELETED;
979 
980  class initiate_async_send
981  {
982  public:
983  typedef Executor executor_type;
984 
985  explicit initiate_async_send(basic_stream_socket* self)
986  : self_(self)
987  {
988  }
989 
990  executor_type get_executor() const ASIO_NOEXCEPT
991  {
992  return self_->get_executor();
993  }
994 
995  template <typename WriteHandler, typename ConstBufferSequence>
996  void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
997  const ConstBufferSequence& buffers,
998  socket_base::message_flags flags) const
999  {
1000  // If you get an error on the following line it means that your handler
1001  // does not meet the documented type requirements for a WriteHandler.
1002  ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1003 
1004  detail::non_const_lvalue<WriteHandler> handler2(handler);
1005  self_->impl_.get_service().async_send(
1006  self_->impl_.get_implementation(), buffers, flags,
1007  handler2.value, self_->impl_.get_executor());
1008  }
1009 
1010  private:
1011  basic_stream_socket* self_;
1012  };
1013 
1014  class initiate_async_receive
1015  {
1016  public:
1017  typedef Executor executor_type;
1018 
1019  explicit initiate_async_receive(basic_stream_socket* self)
1020  : self_(self)
1021  {
1022  }
1023 
1024  executor_type get_executor() const ASIO_NOEXCEPT
1025  {
1026  return self_->get_executor();
1027  }
1028 
1029  template <typename ReadHandler, typename MutableBufferSequence>
1030  void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
1031  const MutableBufferSequence& buffers,
1032  socket_base::message_flags flags) const
1033  {
1034  // If you get an error on the following line it means that your handler
1035  // does not meet the documented type requirements for a ReadHandler.
1036  ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1037 
1038  detail::non_const_lvalue<ReadHandler> handler2(handler);
1039  self_->impl_.get_service().async_receive(
1040  self_->impl_.get_implementation(), buffers, flags,
1041  handler2.value, self_->impl_.get_executor());
1042  }
1043 
1044  private:
1045  basic_stream_socket* self_;
1046  };
1047 };
1048 
1049 } // namespace asio
1050 
1051 #include "asio/detail/pop_options.hpp"
1052 
1053 #endif // ASIO_BASIC_STREAM_SOCKET_HPP
int message_flags
Bitmask type for flags that can be passed to send and receive operations.
Definition: socket_base.hpp:53
std::size_t write_some(const ConstBufferSequence &buffers, asio::error_code &ec)
Write some data to the socket.
Definition: basic_stream_socket.hpp:802
std::size_t read_some(const MutableBufferSequence &buffers)
Read some data from the socket.
Definition: basic_stream_socket.hpp:889
basic_stream_socket(ExecutionContext &context, const endpoint_type &endpoint, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct a basic_stream_socket, opening it and binding it to the given local endpoint.
Definition: basic_stream_socket.hpp:191
basic_socket< Protocol, Executor >::native_handle_type native_handle_type
The native representation of a socket.
Definition: basic_stream_socket.hpp:73
Definition: blocking.hpp:208
basic_stream_socket(const executor_type &ex, const protocol_type &protocol)
Construct and open a basic_stream_socket.
Definition: basic_stream_socket.hpp:127
ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, void(asio::error_code, std::size_t)) async_send(const ConstBufferSequence &buffers
Start an asynchronous send.
Provides stream-oriented socket functionality.
Definition: basic_stream_socket.hpp:36
executor_type get_executor() ASIO_NOEXCEPT
Get the executor associated with the object.
Definition: basic_socket.hpp:366
basic_stream_socket(ExecutionContext &context, const protocol_type &protocol, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct and open a basic_stream_socket.
Definition: basic_stream_socket.hpp:146
basic_stream_socket(const executor_type &ex, const protocol_type &protocol, const native_handle_type &native_socket)
Construct a basic_stream_socket on an existing native socket.
Definition: basic_stream_socket.hpp:213
basic_stream_socket(ExecutionContext &context, const protocol_type &protocol, const native_handle_type &native_socket, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct a basic_stream_socket on an existing native socket.
Definition: basic_stream_socket.hpp:235
std::size_t send(const ConstBufferSequence &buffers, socket_base::message_flags flags, asio::error_code &ec)
Send some data on the socket.
Definition: basic_stream_socket.hpp:424
std::size_t receive(const MutableBufferSequence &buffers, socket_base::message_flags flags)
Receive some data on the socket.
Definition: basic_stream_socket.hpp:604
basic_stream_socket(ExecutionContext &context, typename enable_if< is_convertible< ExecutionContext &, execution_context &>::value >::type *=0)
Construct a basic_stream_socket without opening it.
Definition: basic_stream_socket.hpp:107
basic_stream_socket(const executor_type &ex, const endpoint_type &endpoint)
Construct a basic_stream_socket, opening it and binding it to the given local endpoint.
Definition: basic_stream_socket.hpp:169
Protocol::endpoint endpoint_type
The endpoint type.
Definition: basic_stream_socket.hpp:80
std::size_t receive(const MutableBufferSequence &buffers)
Receive some data on the socket.
Definition: basic_stream_socket.hpp:564
std::size_t send(const ConstBufferSequence &buffers)
Send some data on the socket.
Definition: basic_stream_socket.hpp:358
Definition: type_traits.hpp:97
Definition: non_const_lvalue.hpp:27
std::size_t write_some(const ConstBufferSequence &buffers)
Write some data to the socket.
Definition: basic_stream_socket.hpp:776
detail::reactive_socket_service< Protocol >::native_handle_type native_handle_type
The native representation of a socket.
Definition: basic_socket.hpp:92
Protocol protocol_type
The protocol type.
Definition: basic_stream_socket.hpp:77
Executor executor_type
The type of the executor associated with the object.
Definition: basic_stream_socket.hpp:58
std::size_t send(const ConstBufferSequence &buffers, socket_base::message_flags flags)
Send some data on the socket.
Definition: basic_stream_socket.hpp:395
Class to represent an error code value.
Definition: error_code.hpp:80
Rebinds the socket type to another executor.
Definition: basic_stream_socket.hpp:62
std::size_t read_some(const MutableBufferSequence &buffers, asio::error_code &ec)
Read some data from the socket.
Definition: basic_stream_socket.hpp:916
Provides socket functionality.
Definition: basic_socket.hpp:52
basic_stream_socket< Protocol, Executor1 > other
The socket type when rebound to the specified executor.
Definition: basic_stream_socket.hpp:65
basic_stream_socket(const executor_type &ex)
Construct a basic_stream_socket without opening it.
Definition: basic_stream_socket.hpp:91
~basic_stream_socket()
Destroys the socket.
Definition: basic_stream_socket.hpp:328
Definition: any_io_executor.hpp:28
std::size_t receive(const MutableBufferSequence &buffers, socket_base::message_flags flags, asio::error_code &ec)
Receive some data on a connected socket.
Definition: basic_stream_socket.hpp:633