可以使用的。LZ可以参考一下iptables实现代码中libipq.c和libipq.h,这个里面是封装了基于Netlink的IP Queue机制,里面使用了select机制。
static ssize_t ipq_netlink_recvfrom(const struct ipq_handle *h,
unsigned char *buf, size_t len,
int timeout)
{
int addrlen, status;
struct nlmsghdr *nlh;
if (len < sizeof(struct nlmsgerr)) {
ipq_errno = IPQ_ERR_RECVBUF;
return -1;
}
addrlen = sizeof(h->peer);
if (timeout != 0) {
int ret;
struct timeval tv;
fd_set read_fds;
if (timeout < 0) {
/* non-block non-timeout */
tv.tv_sec = 0;
tv.tv_usec = 0;
} else {
tv.tv_sec = timeout / 1000000;
tv.tv_usec = timeout % 1000000;
}
FD_ZERO(&read_fds);
FD_SET(h->fd, &read_fds);
ret = select(h->fd+1, &read_fds, NULL, NULL, &tv);
if (ret < 0) {
if (errno == EINTR) {
return 0;
} else {
ipq_errno = IPQ_ERR_RECV;
return -1;
}
}
if (!FD_ISSET(h->fd, &read_fds)) {
ipq_errno = IPQ_ERR_TIMEOUT;
return 0;
}
}
status = recvfrom(h->fd, buf, len, 0,
(struct sockaddr *)&h->peer, &addrlen);
if (status < 0) {
ipq_errno = IPQ_ERR_RECV;
return status;
}
if (addrlen != sizeof(h->peer)) {
ipq_errno = IPQ_ERR_RECV;
return -1;
}
if (h->peer.nl_pid != 0) {
ipq_errno = IPQ_ERR_RECV;
return -1;
}
if (status == 0) {
ipq_errno = IPQ_ERR_NLEOF;
return -1;
}
nlh = (struct nlmsghdr *)buf;
if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status) {
ipq_errno = IPQ_ERR_RTRUNC;
return -1;
}
return status;
}