|
|
#include "unix_socket.hpp"
using namespace iflytop; using namespace std; using namespace core; int UnixScoket::initRxSocket() { sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0); if (sock_fd == -1) { logger->error("socket creation failed: {}", strerror(errno)); return -1; }
// Remove socket file if it already exists
unlink(m_path.c_str()); if (bind(sock_fd, (struct sockaddr *)&rx_addr, sizeof(rx_addr)) == -1) { logger->error("bind failed: {}", strerror(errno)); close(sock_fd); sock_fd = -1; return -1; }
// 设置超时时间为5秒
struct timeval tv; tv.tv_sec = 1; // 秒
tv.tv_usec = 0; // 微秒
// 设置SO_RCVTIMEO选项
if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { logger->error("setsockopt failed: {}", strerror(errno)); close(sock_fd); sock_fd = -1; return -1; } return 0; } void UnixScoket::start() { logger->info("Creating UNIX domain socket at path: {}", m_path); logger->info("Connecting to opposite path: {}", m_opposite_path);
initRxSocket();
m_thread.reset(new Thread("UnixSocketThread", [this]() { uint8_t rxbuffer[1024]; struct sockaddr_un client_addr; ThisThread thisThread; while (!thisThread.getExitFlag()) { if (sock_fd < 0) { usleep(100 * 1000); logger->error("Socket is closed, reinitializing..."); initRxSocket(); continue; }
memset(rxbuffer, 0, sizeof(rxbuffer)); socklen_t client_len = sizeof(client_addr); ssize_t num_bytes = recvfrom(sock_fd, rxbuffer, sizeof(rxbuffer) - 1, 0, (struct sockaddr *)&client_addr, &client_len); if (num_bytes > 0) { onPacket(rxbuffer, num_bytes); } if (num_bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // 超时错误
logger->info("recvfrom timed out, no data received"); continue; } else { logger->error("recvfrom failed: {}", strerror(errno)); close(sock_fd); sock_fd = -1; continue; } } } close(sock_fd); unlink(m_path.c_str()); })); } void UnixScoket::sendPacket(uint8_t *data, size_t len) { int ret = sendto(sock_fd, data, len, 0, (struct sockaddr *)&tx_addr, sizeof(tx_addr)); if (ret == -1) { logger->error("sendto failed: {}", strerror(errno)); } }
|