You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.3 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. #include "unix_socket.hpp"
  2. using namespace iflytop;
  3. using namespace std;
  4. using namespace core;
  5. int UnixScoket::initRxSocket() {
  6. sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
  7. if (sock_fd == -1) {
  8. logger->error("socket creation failed: {}", strerror(errno));
  9. return -1;
  10. }
  11. // Remove socket file if it already exists
  12. unlink(m_path.c_str());
  13. if (bind(sock_fd, (struct sockaddr *)&rx_addr, sizeof(rx_addr)) == -1) {
  14. logger->error("bind failed: {}", strerror(errno));
  15. close(sock_fd);
  16. sock_fd = -1;
  17. return -1;
  18. }
  19. // 设置超时时间为5秒
  20. struct timeval tv;
  21. tv.tv_sec = 1; // 秒
  22. tv.tv_usec = 0; // 微秒
  23. // 设置SO_RCVTIMEO选项
  24. if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
  25. logger->error("setsockopt failed: {}", strerror(errno));
  26. close(sock_fd);
  27. sock_fd = -1;
  28. return -1;
  29. }
  30. return 0;
  31. }
  32. void UnixScoket::start() {
  33. logger->info("Creating UNIX domain socket at path: {}", m_path);
  34. logger->info("Connecting to opposite path: {}", m_opposite_path);
  35. initRxSocket();
  36. m_thread.reset(new Thread("UnixSocketThread", [this]() {
  37. uint8_t rxbuffer[1024];
  38. struct sockaddr_un client_addr;
  39. ThisThread thisThread;
  40. while (!thisThread.getExitFlag()) {
  41. if (sock_fd < 0) {
  42. usleep(100 * 1000);
  43. logger->error("Socket is closed, reinitializing...");
  44. initRxSocket();
  45. continue;
  46. }
  47. memset(rxbuffer, 0, sizeof(rxbuffer));
  48. socklen_t client_len = sizeof(client_addr);
  49. ssize_t num_bytes = recvfrom(sock_fd, rxbuffer, sizeof(rxbuffer) - 1, 0, (struct sockaddr *)&client_addr, &client_len);
  50. if (num_bytes > 0) {
  51. onPacket(rxbuffer, num_bytes);
  52. }
  53. if (num_bytes < 0) {
  54. if (errno == EAGAIN || errno == EWOULDBLOCK) { // 超时错误
  55. logger->info("recvfrom timed out, no data received");
  56. continue;
  57. } else {
  58. logger->error("recvfrom failed: {}", strerror(errno));
  59. close(sock_fd);
  60. sock_fd = -1;
  61. continue;
  62. }
  63. }
  64. }
  65. close(sock_fd);
  66. unlink(m_path.c_str());
  67. }));
  68. }
  69. void UnixScoket::sendPacket(uint8_t *data, size_t len) {
  70. int ret = sendto(sock_fd, data, len, 0, (struct sockaddr *)&tx_addr, sizeof(tx_addr));
  71. if (ret == -1) {
  72. logger->error("sendto failed: {}", strerror(errno));
  73. }
  74. }