netlink socket可以使用select函数么

可以使用的。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;
}

你可能感兴趣的:(netlink socket可以使用select函数么)