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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值