platform_net_socket.c 3.2 KB

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