You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.2 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "xsync_udp_factory_impl.hpp"
  2. #include "zqthread.hpp"
  3. //
  4. #include <winsock2.h>
  5. //
  6. #include <Windows.h>
  7. #define ENABLE_LOG
  8. #ifdef ENABLE_LOG
  9. #include "../src/logger.hpp"
  10. #endif
  11. #define TAG "XSYNC_UDP"
  12. #pragma comment(lib, "ws2_32")
  13. using namespace xsync;
  14. using namespace iflytop;
  15. /*******************************************************************************
  16. * XSUDP *
  17. *******************************************************************************/
  18. #define USB_NO_BLOCK_UDP 0
  19. class XSUDP : public I_XSUDP {
  20. uint32_t m_ip;
  21. int m_localport;
  22. struct sockaddr_in localadd = {};
  23. int m_sock_fd = 0;
  24. unique_ptr<ZQThread> m_zq_thread;
  25. onMessage_t m_onMessage;
  26. char* m_rxbuf = nullptr;
  27. size_t m_rxbufsize = 0;
  28. public:
  29. virtual xs_error_code_t initialize(string ip, int localport) override;
  30. virtual xs_error_code_t sendto(const XsyncNetAdd& to, const char* data, int32_t length, int32_t* sendlength) override;
  31. virtual xs_error_code_t receive(char* data, int32_t& length, XsyncNetAdd& from, int overtimems) override;
  32. virtual xs_error_code_t startReceive(onMessage_t onMessage) override;
  33. virtual xs_error_code_t stopReceive() override;
  34. virtual xs_error_code_t clearRxBuffer() override;
  35. virtual ~XSUDP();
  36. };
  37. const char* fmtip(uint32_t ip) {
  38. static char ipstr[16];
  39. sprintf(ipstr, "%d.%d.%d.%d", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
  40. return ipstr;
  41. }
  42. xs_error_code_t XSUDP::initialize(string ip, int localport) {
  43. localadd.sin_family = AF_INET;
  44. localadd.sin_addr.s_addr = inet_addr(ip.c_str());
  45. localadd.sin_port = htons(localport);
  46. // 创建客户端用于通信的Socket
  47. m_sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  48. if (m_sock_fd < 0) return kxs_ec_socket_fail;
  49. int ret = bind(m_sock_fd, (struct sockaddr*)&localadd, sizeof(localadd));
  50. if (ret < 0) return kxs_ec_bind_fail;
  51. #if USB_NO_BLOCK_UDP
  52. u_long mode = 1;
  53. if (ioctlsocket(m_sock_fd, FIONBIO, &mode) != NO_ERROR) {
  54. return kxs_ec_setsockopt_rx_timeout_fail;
  55. }
  56. #endif
  57. return kxs_ec_success;
  58. }
  59. xs_error_code_t XSUDP::sendto(const XsyncNetAdd& to, const char* data, int32_t length, int32_t* sendlength) {
  60. struct sockaddr_in sockaddr;
  61. sockaddr.sin_family = AF_INET;
  62. sockaddr.sin_addr.s_addr = inet_addr(to.ip.c_str());
  63. sockaddr.sin_port = htons(to.port);
  64. int ret = ::sendto(m_sock_fd, data, length, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
  65. if (sendlength) *sendlength = ret;
  66. if (ret >= 0) {
  67. return kxs_ec_success;
  68. }
  69. return kxs_ec_send_fail;
  70. }
  71. xs_error_code_t XSUDP::receive(char* data, int32_t& length, XsyncNetAdd& from, int overtimems) {
  72. #if USB_NO_BLOCK_UDP
  73. struct sockaddr_in sockaddr = {0};
  74. int32_t overtime_10ms = overtimems / 10;
  75. int ret = 0;
  76. overtime_10ms += 1;
  77. for (size_t i = 0;; i++) {
  78. int senderAddressLen = sizeof(sockaddr);
  79. ret = ::recvfrom(m_sock_fd, (char*)data, length, 0, (struct sockaddr*)&sockaddr, &senderAddressLen);
  80. length = ret;
  81. if (ret > 0) break;
  82. if (i >= overtime_10ms) break;
  83. Sleep(10);
  84. }
  85. if (ret <= 0) {
  86. return kxs_ec_overtime;
  87. }
  88. uint32_t ip = ntohl(sockaddr.sin_addr.s_addr);
  89. from.ip = string(fmtip(ip));
  90. from.port = ntohs(sockaddr.sin_port);
  91. return kxs_ec_success;
  92. #else
  93. struct sockaddr_in sockaddr = {0};
  94. timeval timeout;
  95. timeout.tv_sec = overtimems; // 这个结构体的单位是ms,不是秒
  96. timeout.tv_usec = 0;
  97. if (timeout.tv_sec == 0) {
  98. timeout.tv_sec = 1;
  99. }
  100. if (setsockopt(m_sock_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)) == -1) {
  101. return kxs_ec_setsockopt_rx_timeout_fail;
  102. }
  103. int senderAddressLen = sizeof(sockaddr);
  104. int ret = ::recvfrom(m_sock_fd, (char*)data, length, 0, (struct sockaddr*)&sockaddr, &senderAddressLen);
  105. length = ret;
  106. data[length] = 0;
  107. if (ret < 0) {
  108. // ZLOGI(TAG, "recvfrom error %d %s", ret, strerror(errno));
  109. // if (errno == EWOULDBLOCK || errno == EAGAIN) {
  110. return kxs_ec_overtime;
  111. // } else {
  112. // return kxs_ec_receive_fail;
  113. // }
  114. }
  115. // inet_ntop(AF_INET, &(sockaddr.sin_addr), ip, INET_ADDRSTRLEN);
  116. uint32_t ip = ntohl(sockaddr.sin_addr.s_addr);
  117. from.ip = string(fmtip(ip));
  118. from.port = ntohs(sockaddr.sin_port);
  119. return kxs_ec_success;
  120. #endif
  121. }
  122. xs_error_code_t XSUDP::startReceive(onMessage_t onMessage) {
  123. m_onMessage = onMessage;
  124. if (m_zq_thread) {
  125. return kxs_ec_success;
  126. }
  127. m_rxbuf = (char*)malloc(10240);
  128. m_rxbufsize = 10240;
  129. m_zq_thread.reset(new ZQThread("udplistener_thread", [this]() {
  130. while (!m_zq_thread->isTryExit()) {
  131. memset(m_rxbuf, 0, m_rxbufsize);
  132. int32_t length = m_rxbufsize;
  133. XsyncNetAdd from;
  134. xs_error_code_t ret = receive(m_rxbuf, length, from, 1000);
  135. if (ret == kxs_ec_success) {
  136. if (m_onMessage) m_onMessage(from, (uint8_t*)m_rxbuf, length);
  137. }
  138. }
  139. }));
  140. m_zq_thread->start();
  141. return kxs_ec_success;
  142. }
  143. xs_error_code_t XSUDP::stopReceive() {
  144. if (m_zq_thread) {
  145. m_zq_thread->quit();
  146. m_zq_thread->wait();
  147. m_zq_thread.reset(nullptr);
  148. }
  149. if (!m_rxbuf) {
  150. free(m_rxbuf);
  151. m_rxbuf = nullptr;
  152. m_rxbufsize = 0;
  153. }
  154. }
  155. xs_error_code_t XSUDP::clearRxBuffer() {
  156. #if USB_NO_BLOCK_UDP
  157. char buf[1024];
  158. int32_t length = 1024;
  159. XsyncNetAdd from;
  160. xs_error_code_t ret = kxs_ec_success;
  161. while (ret == kxs_ec_success) {
  162. ret = receive(buf, length, from, 1);
  163. }
  164. #endif
  165. return kxs_ec_success;
  166. }
  167. XSUDP::~XSUDP() {
  168. stopReceive();
  169. if (m_sock_fd > 0) {
  170. closesocket(m_sock_fd);
  171. m_sock_fd = -1;
  172. }
  173. }
  174. /*******************************************************************************
  175. * xSyncUdpFactoryImpl *
  176. *******************************************************************************/
  177. void XSyncUdpFactoryImpl::initialize() {}
  178. XSyncUdpFactoryImpl* XSyncUdpFactoryImpl::Ins() {
  179. static XSyncUdpFactoryImpl instance;
  180. return &instance;
  181. }
  182. shared_ptr<I_XSUDP> XSyncUdpFactoryImpl::createXSUDP() { return make_shared<XSUDP>(); }