tcp.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "tcp.h"
  2. #include <arpa/inet.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <netdb.h>
  6. #include <netinet/in.h>
  7. #include <netinet/ip.h>
  8. #include <netinet/tcp.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <sys/ioctl.h>
  13. #include <sys/socket.h>
  14. #include <sys/types.h>
  15. #include <unistd.h>
  16. #define DBG_ENABLE
  17. #define DBG_COLOR
  18. #define DBG_SECTION_NAME "tcp"
  19. #define DBG_LEVEL DBG_LOG
  20. #include "dbg_log.h"
  21. int tcp_listen(int port, int nb_connection)
  22. {
  23. int new_s;
  24. int enable;
  25. int flags;
  26. struct sockaddr_in addr;
  27. flags = SOCK_STREAM;
  28. #ifdef SOCK_CLOEXEC
  29. flags |= SOCK_CLOEXEC;
  30. #endif
  31. new_s = socket(PF_INET, flags, IPPROTO_TCP);
  32. if (new_s == -1) {
  33. return -1;
  34. }
  35. enable = 1;
  36. if (setsockopt(new_s, SOL_SOCKET, SO_REUSEADDR,
  37. (char *)&enable, sizeof(enable)) == -1) {
  38. close(new_s);
  39. return -1;
  40. }
  41. memset(&addr, 0, sizeof(addr));
  42. addr.sin_family = AF_INET;
  43. /* If the modbus port is < to 1024, we need the setuid root. */
  44. addr.sin_port = htons(port);
  45. /* Listen any addresses */
  46. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  47. if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  48. close(new_s);
  49. return -1;
  50. }
  51. if (listen(new_s, nb_connection) == -1) {
  52. close(new_s);
  53. return -1;
  54. }
  55. flags = fcntl(new_s, F_GETFL, 0);
  56. flags |= O_NONBLOCK;
  57. fcntl(new_s, F_SETFL, flags);
  58. flags = fcntl(new_s, F_GETFD);
  59. flags |= FD_CLOEXEC;
  60. fcntl(new_s, F_SETFD, flags);
  61. return new_s;
  62. }
  63. int tcp_accept(int s)
  64. {
  65. struct sockaddr_in addr;
  66. socklen_t addrlen;
  67. int new_s;
  68. addrlen = sizeof(addr);
  69. #ifdef HAVE_ACCEPT4
  70. /* Inherit socket flags and use accept4 call */
  71. new_s = accept4(s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC);
  72. #else
  73. new_s = accept(s, (struct sockaddr *)&addr, &addrlen);
  74. #endif
  75. if (new_s == -1) {
  76. return -1;
  77. }
  78. LOG_I("The client connection from %s is accepted", inet_ntoa(addr.sin_addr));
  79. return new_s;
  80. }
  81. void tcp_close(int s)
  82. {
  83. if (s != -1) {
  84. shutdown(s, SHUT_RDWR);
  85. close(s);
  86. }
  87. }
  88. int tcp_send(int s, const uint8_t *buf, int length)
  89. {
  90. return send(s, buf, length, MSG_NOSIGNAL);
  91. }
  92. int tcp_receive(int s, uint8_t *buf, int bufsz, int timeout)
  93. {
  94. int len = 0;
  95. int rc = 0;
  96. fd_set readset, exceptset;
  97. struct timeval tv;
  98. while (bufsz > 0) {
  99. FD_ZERO(&readset);
  100. FD_ZERO(&exceptset);
  101. FD_SET(s, &readset);
  102. FD_SET(s, &exceptset);
  103. tv.tv_sec = timeout / 1000;
  104. tv.tv_usec = (timeout % 1000) * 1000;
  105. rc = select(s + 1, &readset, NULL, &exceptset, &tv);
  106. if (rc == -1) {
  107. if (errno == EINTR) {
  108. continue;
  109. }
  110. }
  111. if (rc <= 0)
  112. break;
  113. if (FD_ISSET(s, &exceptset)) {
  114. rc = -1;
  115. break;
  116. }
  117. rc = recv(s, buf + len, bufsz, MSG_DONTWAIT);
  118. if (rc < 0)
  119. break;
  120. if (rc == 0) {
  121. if (len == 0)
  122. rc = -1;
  123. break;
  124. }
  125. len += rc;
  126. bufsz -= rc;
  127. timeout = 50;
  128. }
  129. if (rc >= 0)
  130. rc = len;
  131. return rc;
  132. }
  133. int tcp_flush(int s)
  134. {
  135. int rc;
  136. do {
  137. uint8_t devnull[100];
  138. if (s == -1)
  139. break;
  140. rc = recv(s, devnull, sizeof(devnull), MSG_DONTWAIT);
  141. } while (rc == 100);
  142. return 0;
  143. }
  144. int tcp_connect(const char *ip, int port)
  145. {
  146. int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  147. if (s == -1)
  148. return -1;
  149. int option = 1;
  150. int rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const void *)&option, sizeof(int));
  151. if (rc == -1) {
  152. close(s);
  153. s = -1;
  154. return -1;
  155. }
  156. struct timeval tv;
  157. tv.tv_sec = 20;
  158. tv.tv_usec = 0;
  159. rc = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const void *)&tv, sizeof(struct timeval));
  160. if (rc == -1) {
  161. close(s);
  162. s = -1;
  163. return -1;
  164. }
  165. struct sockaddr_in addr;
  166. memset(&addr, 0, sizeof(addr));
  167. addr.sin_family = AF_INET;
  168. addr.sin_port = htons(port);
  169. addr.sin_addr.s_addr = inet_addr(ip);
  170. rc = connect(s, (struct sockaddr *)&addr, sizeof(addr));
  171. if (rc == -1) {
  172. close(s);
  173. s = -1;
  174. return -1;
  175. }
  176. return s;
  177. }