关于4.x内核的内核态socket编程问题(sock_create_kern)

本文详细介绍了在Linux内核态下使用socket编程的过程,包括sock_create_kern、kernel_setsockopt、kernel_bind等关键函数的使用,并对比了从2.x到4.x版本中sock_create_kern函数的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于4.x内核的内核态socket编程问题(sock_create_kern)

tags : linux socket


linux内核态socket编程如何实现:(以tcp服务端举例)

1、sock_create_kern()
2、kernel_setsockopt()这一步为可去掉的,但是如果想socket进行配置,则需要此步骤,例如配置成非阻塞模式:

struct timeval tv;

tv.tv_sec = 0;
tv.tv_usec = 1000 * RECV_WATI_TIME_MS;
kernel_setsockopt(sock_srv, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));

3、kernel_bind()
4、kernel_listen()
5、kernel_accept()
6、kernel_sendmsg()/kernel_recvmsg()
7、sock_release()

其他的也都类似,这里不记录了。

关于不同版本的linux对于sock_create_kern函数的定义

linux2.x的版本

int sock_create_kern(int family, int type, int protocol, struct socket **res)
{
    return __sock_create(family, type, protocol, res, 1);
}

linux3.x的版本:

int sock_create_kern(int family, int type, int protocol, struct socket **res)
{
    return __sock_create(&init_net, family, type, protocol, res, 1);
}

linux4.x的版本

int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
{
    return __sock_create(net, family, type, protocol, res, 1);
}

所以,这里在4.x版本里面创建socket的话,最简单的方式是这样调用:

sock_create_kern(&init_net, family, type, protocol, res);

还有一个create socket的函数不要用!!!

int sock_create(int family, int type, int protocol, struct socket **res)
{
    return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
}

如果用这个函数创建socket,可以成功的bind、listen、accept,但是一到sendmesg、recvmesg就会出现permission denied。

先在这里插个眼,今后有空的时候再来研究下struct net *net相关的内容,把原因补上。

内核态中,可以通过注册 Netlink 套接字的回调函数来监测 Netlink 连接的断开。当连接断开时,内核会调用注册的回调函数,从而可以在回调函数中执行相应的处理逻辑。 以下是一个示例代码,展示了如何在内核态监测 Netlink 连接的断开: ```c #include <linux/netlink.h> struct sock *nl_sock; // Netlink 套接字 void netlink_disconnect(struct sock *sk) { // 处理连接断开的逻辑 } struct netlink_kernel_cfg cfg = { .input = NULL, .cb_flags = NL_CB_DISABLE, .groups = 0, .flags = 0, .bind = NULL, .unbind = netlink_disconnect, // 注册连接断开的回调函数 }; int init_module(void) { nl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, &cfg); if (!nl_sock) { printk(KERN_ERR "Failed to create Netlink socket\n"); return -ENOMEM; } // 其他初始化操作 return 0; } void cleanup_module(void) { if (nl_sock) { netlink_kernel_release(nl_sock); nl_sock = NULL; } // 其他清理操作 } ``` 在上述示例中,我们定义了一个 `netlink_disconnect` 函数作为连接断开的回调函数。当连接断开时,内核会调用这个函数,并将对应的 Netlink 套接字传递给它。您可以在这个函数中编写处理连接断开的逻辑,例如释放资源、清理状态等。 在 `cfg` 结构体中,我们将 `unbind` 字段设置为 `netlink_disconnect` 函数,从而注册连接断开的回调函数。 在 `init_module` 函数中,我们使用 `netlink_kernel_create` 函数创建 Netlink 套接字,并将配置结构体 `cfg` 传递给它。在这个函数中,我们也进行了其他的初始化操作。 在 `cleanup_module` 函数中,我们释放了创建的 Netlink 套接字,并进行了其他的清理操作。 请注意,这只是一个简单的示例代码,您可能需要根据实际需求进行修改和扩展。同时,还可以根据需要在回调函数中执行其他操作,例如发送通知、记录日志等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值