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