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.
 
 

80 lines
2.3 KiB

#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));
}
}