platformNetwork.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "platformNetwork.h"
  2. /**
  3. * @brief 连接mqtt服务器
  4. *
  5. * @param userData
  6. * @param platformNetwork
  7. * @param host
  8. * @param port
  9. * @return RyanMqttError_e
  10. * 成功返回RyanMqttSuccessError, 失败返回错误信息
  11. */
  12. RyanMqttError_e platformNetworkConnect(void *userData, platformNetwork_t *platformNetwork, const char *host, const char *port)
  13. {
  14. RyanMqttError_e result = RyanMqttSuccessError;
  15. struct addrinfo *addr_list = NULL;
  16. struct addrinfo hints = {
  17. .ai_family = AF_UNSPEC,
  18. .ai_socktype = SOCK_STREAM,
  19. .ai_protocol = IPPROTO_TCP};
  20. if (getaddrinfo(host, port, &hints, &addr_list) != 0)
  21. {
  22. result = RyanMqttSuccessError;
  23. goto exit;
  24. }
  25. platformNetwork->socket = socket(addr_list->ai_family, addr_list->ai_socktype, addr_list->ai_protocol);
  26. if (platformNetwork->socket < 0)
  27. {
  28. result = RyanSocketFailedError;
  29. goto exit;
  30. }
  31. if (connect(platformNetwork->socket, addr_list->ai_addr, addr_list->ai_addrlen) != 0)
  32. {
  33. platformNetworkClose(userData, platformNetwork);
  34. result = RyanMqttSocketConnectFailError;
  35. goto exit;
  36. }
  37. exit:
  38. if (NULL != addr_list)
  39. freeaddrinfo(addr_list);
  40. return result;
  41. }
  42. /**
  43. * @brief 非阻塞接收数据
  44. *
  45. * @param userData
  46. * @param platformNetwork
  47. * @param recvBuf
  48. * @param recvLen
  49. * @param timeout
  50. * @return RyanMqttError_e
  51. * socket错误返回 RyanSocketFailedError
  52. * 接收超时或者接收数据长度不等于期待数据接受长度 RyanMqttRecvPacketTimeOutError
  53. * 接收成功 RyanMqttSuccessError
  54. */
  55. RyanMqttError_e platformNetworkRecvAsync(void *userData, platformNetwork_t *platformNetwork, char *recvBuf, int recvLen, int timeout)
  56. {
  57. int32_t recvResult = 0;
  58. int32_t offset = 0;
  59. int32_t timeOut2 = timeout;
  60. struct timeval tv = {0};
  61. platformTimer_t timer = {0};
  62. if (-1 == platformNetwork->socket)
  63. return RyanSocketFailedError;
  64. platformTimerCutdown(&timer, timeout);
  65. while ((offset < recvLen) && (0 != timeOut2))
  66. {
  67. tv.tv_sec = timeOut2 / 1000;
  68. tv.tv_usec = timeOut2 % 1000 * 1000;
  69. if (tv.tv_sec <= 0 && tv.tv_usec <= 100)
  70. {
  71. tv.tv_sec = 0;
  72. tv.tv_usec = 100;
  73. }
  74. setsockopt(platformNetwork->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); // 设置错做模式为非阻塞
  75. recvResult = recv(platformNetwork->socket, recvBuf, recvLen - offset, 0);
  76. if (recvResult < 0) // 小于零,表示错误,个别错误不代表socket错误
  77. {
  78. // 下列3种表示没问题,但需要推出发送
  79. if ((errno == EAGAIN || // 套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
  80. errno == EWOULDBLOCK || // 发送时套接字发送缓冲区已满,或接收时套接字接收缓冲区为空
  81. errno == EINTR)) // 操作被信号中断
  82. break;
  83. return RyanSocketFailedError;
  84. }
  85. offset += recvResult;
  86. timeOut2 = platformTimerRemain(&timer);
  87. }
  88. if (offset != recvLen)
  89. return RyanMqttRecvPacketTimeOutError;
  90. return RyanMqttSuccessError;
  91. }
  92. /**
  93. * @brief 非阻塞发送数据
  94. *
  95. * @param userData
  96. * @param platformNetwork
  97. * @param sendBuf
  98. * @param sendLen
  99. * @param timeout
  100. * @return RyanMqttError_e
  101. * socket错误返回 RyanSocketFailedError
  102. * 接收超时或者接收数据长度不等于期待数据接受长度 RyanMqttRecvPacketTimeOutError
  103. * 接收成功 RyanMqttSuccessError
  104. */
  105. RyanMqttError_e platformNetworkSendAsync(void *userData, platformNetwork_t *platformNetwork, char *sendBuf, int sendLen, int timeout)
  106. {
  107. int32_t sendResult = 0;
  108. int32_t offset = 0;
  109. int32_t timeOut2 = timeout;
  110. struct timeval tv = {0};
  111. platformTimer_t timer = {0};
  112. if (-1 == platformNetwork->socket)
  113. return RyanSocketFailedError;
  114. platformTimerCutdown(&timer, timeout);
  115. while ((offset < sendLen) && (0 != timeOut2))
  116. {
  117. tv.tv_sec = timeOut2 / 1000;
  118. tv.tv_usec = timeOut2 % 1000 * 1000;
  119. if (tv.tv_sec <= 0 && tv.tv_usec <= 100)
  120. {
  121. tv.tv_sec = 0;
  122. tv.tv_usec = 100;
  123. }
  124. setsockopt(platformNetwork->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); // 设置错做模式为非阻塞
  125. sendResult = send(platformNetwork->socket, sendBuf, sendLen - offset, 0);
  126. if (sendResult < 0) // 小于零,表示错误,个别错误不代表socket错误
  127. {
  128. // 下列3种表示没问题,但需要推出发送
  129. if ((errno == EAGAIN || // 套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
  130. errno == EWOULDBLOCK || // 发送时套接字发送缓冲区已满,或接收时套接字接收缓冲区为空
  131. errno == EINTR)) // 操作被信号中断
  132. break;
  133. return RyanSocketFailedError;
  134. }
  135. offset += sendResult;
  136. timeOut2 = platformTimerRemain(&timer);
  137. }
  138. if (offset != sendLen)
  139. return RyanMqttSendPacketTimeOutError;
  140. return RyanMqttSuccessError;
  141. }
  142. /**
  143. * @brief 断开mqtt服务器连接
  144. *
  145. * @param userData
  146. * @param platformNetwork
  147. * @return RyanMqttError_e
  148. */
  149. RyanMqttError_e platformNetworkClose(void *userData, platformNetwork_t *platformNetwork)
  150. {
  151. if (platformNetwork->socket >= 0)
  152. {
  153. closesocket(platformNetwork->socket);
  154. platformNetwork->socket = -1;
  155. }
  156. return RyanMqttSuccessError;
  157. }