platform_net_socket.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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 information and source code according to the license.
  7. */
  8. #include "platform_net_socket.h"
  9. #include "mqtt_error.h"
  10. int platform_net_socket_connect(const char *host, const char *port, int proto)
  11. {
  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. memset(&hints, 0, sizeof(hints));
  16. hints.ai_family = AF_UNSPEC;
  17. hints.ai_socktype = (proto == PLATFORM_NET_PROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
  18. hints.ai_protocol = (proto == PLATFORM_NET_PROTO_UDP) ? IPPROTO_UDP : IPPROTO_TCP;
  19. if (getaddrinfo(host, port, &hints, &addr_list) != 0) {
  20. return ret;
  21. }
  22. for (cur = addr_list; cur != NULL; cur = cur->ai_next) {
  23. fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
  24. if (fd < 0) {
  25. ret = MQTT_SOCKET_FAILED_ERROR;
  26. continue;
  27. }
  28. if (connect(fd, cur->ai_addr, cur->ai_addrlen) == 0) {
  29. ret = fd;
  30. break;
  31. } else
  32. {
  33. perror("connect");
  34. }
  35. close(fd);
  36. ret = MQTT_CONNECT_FAILED_ERROR;
  37. }
  38. freeaddrinfo(addr_list);
  39. return ret;
  40. }
  41. int platform_net_socket_recv(int fd, void *buf, size_t len, int flags)
  42. {
  43. return recv(fd, buf, len, flags);
  44. }
  45. int platform_net_socket_recv_timeout(int fd, unsigned char *buf, int len, int timeout)
  46. {
  47. int nread;
  48. int nleft = len;
  49. unsigned char *ptr;
  50. ptr = buf;
  51. struct timeval tv = {
  52. timeout / 1000,
  53. (timeout % 1000) * 1000
  54. };
  55. if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec <= 0)) {
  56. tv.tv_sec = 0;
  57. tv.tv_usec = 100;
  58. }
  59. platform_net_socket_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
  60. while (nleft > 0) {
  61. nread = platform_net_socket_recv(fd, ptr, nleft, 0);
  62. if (nread < 0) {
  63. return -1;
  64. } else if (nread == 0) {
  65. break;
  66. }
  67. nleft -= nread;
  68. ptr += nread;
  69. }
  70. return len - nleft;
  71. }
  72. int platform_net_socket_write(int fd, void *buf, size_t len)
  73. {
  74. return write(fd, buf, len);
  75. }
  76. int platform_net_socket_write_timeout(int fd, unsigned char *buf, int len, int timeout)
  77. {
  78. struct timeval tv = {
  79. timeout / 1000,
  80. (timeout % 1000) * 1000
  81. };
  82. if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec <= 0)) {
  83. tv.tv_sec = 0;
  84. tv.tv_usec = 100;
  85. }
  86. setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv,sizeof(struct timeval));
  87. return write(fd, buf, len);
  88. }
  89. int platform_net_socket_close(int fd)
  90. {
  91. return close(fd);
  92. }
  93. int platform_net_socket_set_block(int fd)
  94. {
  95. return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, F_GETFL) & ~O_NONBLOCK);
  96. }
  97. int platform_net_socket_set_nonblock(int fd)
  98. {
  99. return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, F_GETFL) | O_NONBLOCK);
  100. }
  101. int platform_net_socket_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
  102. {
  103. return setsockopt(fd, level, optname, optval, optlen);
  104. }