socket_utils.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "socket_utils.h"
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <netinet/in.h>
  5. #include <sys/socket.h>
  6. #include <unistd.h>
  7. #include "esp_log.h"
  8. static const char *TAG = "sock_utils";
  9. int socket_utils_bind_udp(uint16_t port, int recv_timeout_sec, int recvbuf_size,
  10. uint16_t *bound_port) {
  11. int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  12. if (sock < 0) {
  13. ESP_LOGE(TAG, "Failed to create UDP socket: errno=%d", errno);
  14. return -1;
  15. }
  16. if (recv_timeout_sec > 0) {
  17. struct timeval tv = {.tv_sec = recv_timeout_sec, .tv_usec = 0};
  18. setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  19. }
  20. if (recvbuf_size > 0) {
  21. setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recvbuf_size,
  22. sizeof(recvbuf_size));
  23. }
  24. struct sockaddr_in addr = {0};
  25. addr.sin_family = AF_INET;
  26. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  27. addr.sin_port = htons(port);
  28. if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
  29. ESP_LOGE(TAG, "Failed to bind UDP socket to port %u: %d", port, errno);
  30. close(sock);
  31. return -1;
  32. }
  33. if (bound_port) {
  34. socklen_t addr_len = sizeof(addr);
  35. getsockname(sock, (struct sockaddr *)&addr, &addr_len);
  36. *bound_port = ntohs(addr.sin_port);
  37. }
  38. return sock;
  39. }
  40. int socket_utils_bind_tcp_listener(uint16_t port, int backlog, bool nonblocking,
  41. uint16_t *bound_port) {
  42. int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  43. if (sock < 0) {
  44. ESP_LOGE(TAG, "Failed to create TCP socket: errno=%d", errno);
  45. return -1;
  46. }
  47. int opt = 1;
  48. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  49. struct sockaddr_in addr = {0};
  50. addr.sin_family = AF_INET;
  51. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  52. addr.sin_port = htons(port);
  53. if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
  54. ESP_LOGE(TAG, "Failed to bind TCP socket to port %u: %d", port, errno);
  55. close(sock);
  56. return -1;
  57. }
  58. if (listen(sock, backlog) < 0) {
  59. ESP_LOGE(TAG, "Failed to listen on TCP socket: %d", errno);
  60. close(sock);
  61. return -1;
  62. }
  63. if (nonblocking) {
  64. int flags = fcntl(sock, F_GETFL, 0);
  65. fcntl(sock, F_SETFL, flags | O_NONBLOCK);
  66. }
  67. if (bound_port) {
  68. socklen_t addr_len = sizeof(addr);
  69. getsockname(sock, (struct sockaddr *)&addr, &addr_len);
  70. *bound_port = ntohs(addr.sin_port);
  71. }
  72. return sock;
  73. }