udp_send_op.hpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.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. #ifndef __ASIO2_UDP_SEND_OP_HPP__
  11. #define __ASIO2_UDP_SEND_OP_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <memory>
  16. #include <future>
  17. #include <utility>
  18. #include <string_view>
  19. #include <asio2/base/error.hpp>
  20. namespace asio2::detail
  21. {
  22. template<class derived_t, class args_t>
  23. class udp_send_op
  24. {
  25. public:
  26. /**
  27. * @brief constructor
  28. */
  29. udp_send_op() noexcept {}
  30. /**
  31. * @brief destructor
  32. */
  33. ~udp_send_op() = default;
  34. protected:
  35. template<class Data, class Callback>
  36. inline bool _udp_send(Data& data, Callback&& callback)
  37. {
  38. derived_t& derive = static_cast<derived_t&>(*this);
  39. #if defined(_DEBUG) || defined(DEBUG)
  40. ASIO2_ASSERT(derive.post_send_counter_.load() == 0);
  41. derive.post_send_counter_++;
  42. #endif
  43. derive.stream().async_send(asio::buffer(data),
  44. make_allocator(derive.wallocator(),
  45. [
  46. #if defined(_DEBUG) || defined(DEBUG)
  47. &derive,
  48. #endif
  49. callback = std::forward<Callback>(callback)
  50. ]
  51. (const error_code& ec, std::size_t bytes_sent) mutable
  52. {
  53. #if defined(_DEBUG) || defined(DEBUG)
  54. derive.post_send_counter_--;
  55. #endif
  56. set_last_error(ec);
  57. callback(ec, bytes_sent);
  58. }));
  59. return true;
  60. }
  61. template<class Endpoint, class Data, class Callback>
  62. inline bool _udp_send_to(Endpoint& endpoint, Data& data, Callback&& callback)
  63. {
  64. derived_t& derive = static_cast<derived_t&>(*this);
  65. #if defined(_DEBUG) || defined(DEBUG)
  66. ASIO2_ASSERT(derive.post_send_counter_.load() == 0);
  67. derive.post_send_counter_++;
  68. #endif
  69. // issue: when on the server, all udp session are used a same socket, so
  70. // multiple sessions maybe use the same socket to send data concurrently
  71. // at the same time. But the test can't detect this problem. On windows
  72. // platform, the WSASendTo always success and return 0.
  73. derive.stream().async_send_to(asio::buffer(data), endpoint,
  74. make_allocator(derive.wallocator(),
  75. [
  76. #if defined(_DEBUG) || defined(DEBUG)
  77. &derive,
  78. #endif
  79. callback = std::forward<Callback>(callback)
  80. ]
  81. (const error_code& ec, std::size_t bytes_sent) mutable
  82. {
  83. #if defined(_DEBUG) || defined(DEBUG)
  84. derive.post_send_counter_--;
  85. #endif
  86. set_last_error(ec);
  87. callback(ec, bytes_sent);
  88. }));
  89. return true;
  90. }
  91. protected:
  92. };
  93. }
  94. #endif // !__ASIO2_UDP_SEND_OP_HPP__