platform_net_socket.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * @Author: jiejie
  3. * @Github: https://github.com/jiejieTop
  4. * @Date: 2020-01-10 23:45:59
  5. * @LastEditTime: 2020-06-05 17:13:00
  6. * @Description: the code belongs to jiejie, please keep the author
  7. * information and source code according to the license.
  8. */
  9. #include "platform_net_socket.h"
  10. #include "mqtt_error.h"
  11. int platform_net_socket_connect(const char* host, const char* port, int proto) {
  12. int fd, ret = MQTT_SOCKET_UNKNOWN_HOST_ERROR;
  13. struct addrinfo hints, *addr_list, *cur;
  14. /* Do name resolution with both IPv6 and IPv4 */
  15. __platform_memset(&hints, 0, sizeof(hints));
  16. hints.ai_family = AF_UNSPEC;
  17. hints.ai_socktype =
  18. (proto == PLATFORM_NET_PROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
  19. hints.ai_protocol =
  20. (proto == PLATFORM_NET_PROTO_UDP) ? IPPROTO_UDP : IPPROTO_TCP;
  21. if (__platform_getaddrinfo(host, port, &hints, &addr_list) != 0) {
  22. return ret;
  23. }
  24. for (cur = addr_list; cur != NULL; cur = cur->ai_next) {
  25. fd = __platform_socket(cur->ai_family, cur->ai_socktype,
  26. cur->ai_protocol);
  27. if (fd < 0) {
  28. ret = MQTT_SOCKET_FAILED_ERROR;
  29. continue;
  30. }
  31. if (__platform_connect(fd, cur->ai_addr, cur->ai_addrlen) == 0) {
  32. ret = fd;
  33. break;
  34. }
  35. __platform_close(fd);
  36. ret = MQTT_CONNECT_FAILED_ERROR;
  37. }
  38. __platform_freeaddrinfo(addr_list);
  39. return ret;
  40. }
  41. int platform_net_socket_recv(int fd, void* buf, size_t len, int flags) {
  42. return __platform_recv(fd, buf, len, flags);
  43. }
  44. int platform_net_socket_recv_timeout(int fd,
  45. unsigned char* buf,
  46. int len,
  47. int timeout) {
  48. int nread;
  49. int nleft = len;
  50. unsigned char* ptr;
  51. ptr = buf;
  52. struct timeval tv = {timeout / 1000, (timeout % 1000) * 1000};
  53. if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec <= 0)) {
  54. tv.tv_sec = 0;
  55. tv.tv_usec = 100;
  56. }
  57. platform_net_socket_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv,
  58. sizeof(struct timeval));
  59. while (nleft > 0) {
  60. nread = platform_net_socket_recv(fd, ptr, nleft, 0);
  61. if (nread < 0) {
  62. return -1;
  63. } else if (nread == 0) {
  64. break;
  65. }
  66. nleft -= nread;
  67. ptr += nread;
  68. }
  69. return len - nleft;
  70. }
  71. int platform_net_socket_write(int fd, void* buf, size_t len) {
  72. return __platform_write(fd, buf, len);
  73. }
  74. int platform_net_socket_write_timeout(int fd,
  75. unsigned char* buf,
  76. int len,
  77. int timeout) {
  78. struct timeval tv = {timeout / 1000, (timeout % 1000) * 1000};
  79. if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec <= 0)) {
  80. tv.tv_sec = 0;
  81. tv.tv_usec = 100;
  82. }
  83. __platform_setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv,
  84. sizeof(struct timeval));
  85. return __platform_write(fd, buf, len);
  86. }
  87. int platform_net_socket_close(int fd) {
  88. return __platform_close(fd);
  89. }
  90. PIKA_WEAK int platform_net_socket_set_block(int fd) {
  91. #ifdef __linux
  92. return __platform_fcntl(
  93. fd, F_SETFL, __platform_fcntl(fd, F_GETFL, F_GETFL) & ~O_NONBLOCK);
  94. #elif defined(_WIN32)
  95. unsigned long mode = 0;
  96. return ioctlsocket(fd, FIONBIO, &mode);
  97. #else
  98. WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
  99. return -1;
  100. #endif
  101. }
  102. PIKA_WEAK int platform_net_socket_set_nonblock(int fd) {
  103. #ifdef __linux
  104. return __platform_fcntl(
  105. fd, F_SETFL, __platform_fcntl(fd, F_GETFL, F_GETFL) | O_NONBLOCK);
  106. #elif defined(_WIN32)
  107. unsigned long mode = 1;
  108. return ioctlsocket(fd, FIONBIO, &mode);
  109. #else
  110. WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
  111. return -1;
  112. #endif
  113. }
  114. PIKA_WEAK int platform_net_socket_setsockopt(int fd,
  115. int level,
  116. int optname,
  117. const void* optval,
  118. socklen_t optlen) {
  119. return __platform_setsockopt(fd, level, optname, optval, optlen);
  120. }