linux下的netlink编程

linux内核编程之netlink 上一节说到proc文件系统,这是用户态和内核态通信的一种方法,本节将要说到另外一种通信的方法,该方法相比于其他的内核和用户通信有时在于: Netlink相对于其他的通信机制具有以下优点: 1.使用Netlink通过自定义一种新的协议并加入协议族即可通过socket API使用Netlink协议完成数据交换,而ioctl和proc文件系统均需要通过程序加入相应的设备或文件。 2.Netlink使用socket缓存队列,是一种异步通信机制,而ioctl是同步通信机制,如果传输的数据量较大,会影响系统性能。 3. 阅读详情

在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,同时还使用 netlink 实现了 ip queue 工具,但 ip queue 的使用有其局限性,不能自由地用于各种中断过程。内核的帮助文档和其他一些 Linux 相关文章都没有对 netlink 套接字在中断过程和用户空间通信的应用上作详细的说明,使得很多用户对此只有一个模糊的概念。

Unicast Communication between Kernel and Application
在下面的例子中,一个用户空间进程发送一个netlink消息给内核模块,内核模块应答一个消息给发送进程,这里是用户空间的代码:

#include  < sys / socket.h >
#include 
< linux / netlink.h >
#define  MAX_PAYLOAD 1024  /* maximum payload size*/
struct  sockaddr_nl src_addr, dest_addr;
struct  msghdr msg;
struct  nlmsghdr  * nlh  =  NULL;
struct  iovec iov;
int  sock_fd;
void  main()  {
 sock_fd 
=  socket(PF_NETLINK, SOCK_RAW,NETLINK_TEST);
 memset(
& src_addr,  0 ,  sizeof (src_addr));
 src__addr.nl_family 
=  AF_NETLINK;      
 src_addr.nl_pid 
=  getpid();   /*  self pid  */
 src_addr.nl_groups 
=   0 ;   /*  not in mcast groups  */
 bind(sock_fd, (
struct  sockaddr * ) & src_addr, 
      
sizeof (src_addr));
 memset(
& dest_addr,  0 ,  sizeof (dest_addr));
 dest_addr.nl_family 
=  AF_NETLINK;
 dest_addr.nl_pid 
=   0 ;    /*  For Linux Kernel  */
 dest_addr.nl_groups 
=   0 ;  /*  unicast  */
 nlh
= ( struct  nlmsghdr  * )malloc(
                         NLMSG_SPACE(MAX_PAYLOAD));
 
/*  Fill the netlink message header  */
 nlh
-> nlmsg_len  =  NLMSG_SPACE(MAX_PAYLOAD);
 nlh
-> nlmsg_pid  =  getpid();   /*  self pid  */
 nlh
-> nlmsg_flags  =   0 ;
 
/*  Fill in the netlink message payload  */
 strcpy(NLMSG_DATA(nlh), 
" Hello you! " );
 iov.iov_base 
=  ( void   * )nlh;
 iov.iov_len 
=  nlh -> nlmsg_len;
 msg.msg_name 
=  ( void   * ) & dest_addr;
 msg.msg_namelen 
=   sizeof (dest_addr);
 msg.msg_iov 
=   & iov;
 msg.msg_iovlen 
=   1 ;
 sendmsg(fd, 
& msg,  0 );
 
/*  Read message from kernel  */
 memset(nlh, 
0 , NLMSG_SPACE(MAX_PAYLOAD));
 recvmsg(fd, 
& msg,  0 );
 printf(
"  Received message payload: %s " , 
        NLMSG_DATA(nlh));
    
 
/*  Close Netlink Socket  */
 close(sock_fd);
}
    

这里是内核代码:

struct  sock  * nl_sk  =  NULL;
void  nl_data_ready ( struct  sock  * sk,  int  len)
{
  wake_up_interruptible(sk
-> sleep);
}

void  netlink_test()  {
 
struct  sk_buff  * skb  =  NULL;
 
struct  nlmsghdr  * nlh  =  NULL;
 
int  err;
 u32 pid;     
 nl_sk 
=  netlink_kernel_create(NETLINK_TEST, 
                                   nl_data_ready);
 
/*  wait for message coming down from user-space  */
 skb 
=  skb_recv_datagram(nl_sk,  0 ,  0 ,  & err);
 nlh 
=  ( struct  nlmsghdr  * )skb -> data;
 printk(
" %s: received netlink message payload:%s " , 
        __FUNCTION__, NLMSG_DATA(nlh));
 pid 
=  nlh -> nlmsg_pid;  /* pid of sending process  */
 NETLINK_CB(skb).groups 
=   0 ;  /*  not in mcast group  */
 NETLINK_CB(skb).pid 
=   0 ;       /*  from kernel  */
 NETLINK_CB(skb).dst_pid 
=  pid;
 NETLINK_CB(skb).dst_groups 
=   0 ;   /*  unicast  */
 netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
 sock_release(nl_sk
-> socket);
}
 

在内核模块被加载到内核,当我们运行用户程序,我们将看到下面的信息:

Received message payload: Hello you!

然后用dmesg我们可以看到内核输出:

netlink_test: received netlink message payload:
Hello you!

Multicast Communication between Kernel and Applications
这个例子中,两个应用程序在监听同一个netlink广播组.内核模块发送一个netlink消息给这个广播组,所用的应用程序都收到它,如下是用户程序代码:

#include  < sys / socket.h >
#include 
< linux / netlink.h >
#define  MAX_PAYLOAD 1024  /* maximum payload size*/
struct  sockaddr_nl src_addr, dest_addr;
struct  nlmsghdr  * nlh  =  NULL;
struct  iovec iov;
int  sock_fd;
void  main()  {
 sock_fd
= socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
 memset(
& src_addr,  0 ,  sizeof (local_addr));
 src_addr.nl_family 
=  AF_NETLINK;       
 src_addr.nl_pid 
=  getpid();   /*  self pid  */
 
/*  interested in group 1<<0  */   
 src_addr.nl_groups 
=   1 ;
 bind(sock_fd, (
struct  sockaddr * ) & src_addr, 
      
sizeof (src_addr));
 memset(
& dest_addr,  0 ,  sizeof (dest_addr)); 
 nlh 
=  ( struct  nlmsghdr  * )malloc(
                          NLMSG_SPACE(MAX_PAYLOAD));
 memset(nlh, 
0 , NLMSG_SPACE(MAX_PAYLOAD));      
    
 iov.iov_base 
=  ( void   * )nlh;
 iov.iov_len 
=  NLMSG_SPACE(MAX_PAYLOAD);
 msg.msg_name 
=  ( void   * ) & dest_addr;
 msg.msg_namelen 
=   sizeof (dest_addr);
 msg.msg_iov 
=   & iov;
 msg.msg_iovlen 
=   1 ;
 printf(
" Waiting for message from kernel " );
 
/*  Read message from kernel  */
 recvmsg(fd, 
& msg,  0 );
 printf(
"  Received message payload: %s " , 
        NLMSG_DATA(nlh));
 close(sock_fd);
}
  

 内核代码:

#define  MAX_PAYLOAD 1024 
struct  sock  * nl_sk  =  NULL;
void  netlink_test()  {
 sturct sk_buff 
* skb  =  NULL;
 
struct  nlmsghdr  * nlh;
 
int  err;
 nl_sk 
=  netlink_kernel_create(NETLINK_TEST, 
                               nl_data_ready);
 skb
= alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
 nlh 
=  ( struct  nlmsghdr  * )skb -> data;
 nlh
-> nlmsg_len  =  NLMSG_SPACE(MAX_PAYLOAD);
 nlh
-> nlmsg_pid  =   0 ;   /*  from kernel  */
 nlh
-> nlmsg_flags  =   0 ;
 strcpy(NLMSG_DATA(nlh), 
" Greeting from kernel! " );
 
/*  sender is in group 1<<0  */
 NETLINK_CB(skb).groups 
=   1 ;
 NETLINK_CB(skb).pid 
=   0 ;   /*  from kernel  */
 NETLINK_CB(skb).dst_pid 
=   0 ;   /*  multicast  */
 
/*  to mcast group 1<<0  */
 NETLINK_CB(skb).dst_groups 
=   1 ;
 
/* multicast the message to all listening processes */
 netlink_broadcast(nl_sk, skb, 
0 ,  1 , GFP_KERNEL);
 sock_release(nl_sk
-> socket);
}
  

我们运行用户程序:

 
./nl_recv &
Waiting for message from kernel
./nl_recv &
Waiting for message from kernel
 
然后我们加载内核模块到内核空间,会看到如下信息::

Received message payload: Greeting from kernel!
Received message payload: Greeting from kernel!

以下是一个简单的测试内核事件的应用程序:

#define  MAX_PAYLOAD        1024
struct  sockaddr_nl    src_addr, dest_addr;
char   * KernelMsg  =  NULL;
struct  iovec iov;
int  sock_fd;
struct  msghdr msg;
int  msglen;

#define  DEVICE_ADD            "add"
#define  DEVICE_REMOVE        "remove"
#define  DEVICE_NAME            "event0"
#define  DEVICE_NAMELEN    6
void   *  DeviceManagement( void   * arg)
{
    sock_fd 
=  socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
    
int  msgle;
    
    memset(
& src_addr,  0 ,  sizeof (src_addr));
    src_addr.nl_family 
=  AF_NETLINK;
    src_addr.nl_pid 
=  pthread_self()  <<   16   |  getpid();
    src_addr.nl_groups 
=   1 ;
    bind(sock_fd, (
struct  sockaddr  * ) & src_addr,  sizeof (src_addr));
    
    memset(
& dest_addr,  0 ,  sizeof (dest_addr));
    KernelMsg 
=  ( struct  nlmsghdr  * )malloc(MAX_PAYLOAD);
    memset(KernelMsg, 
0 ,     MAX_PAYLOAD);
    
    iov.iov_base 
=  ( void   * )KernelMsg;
    iov.iov_len 
=  MAX_PAYLOAD;
    msg.msg_name 
=  ( void   * ) & dest_addr;
    msg.msg_namelen 
=   sizeof (dest_addr);
    msg.msg_iov 
=   & iov;
    msg.msg_iovlen 
=   1 ;
    
    
while ( 1 )  {
        
// printf("Waiting for message from kernel ");
        recvmsg(sock_fd,  & msg,  0 );
        
// printf("Receved message payload: %s ", KernelMsg);
        msglen  =  strlen(KernelMsg);
        
// printf("Device: %s ", KernelMsg+msglen-DEVICE_NAMELEN);
         if ( ! strncmp(DEVICE_NAME, KernelMsg + msglen - DEVICE_NAMELEN, DEVICE_NAMELEN))  {
            
if ( ! strncmp(DEVICE_ADD, KernelMsg, strlen(DEVICE_ADD))) 
            
{
                printf(
" Add event0 device " );
                USBKeyboardReady 
=   1 ;
            }

            
else   if ( ! strncmp(DEVICE_REMOVE, KernelMsg, strlen(DEVICE_REMOVE)))  {
                printf(
" Remove event0 device " );
                USBKeyboardReady 
=   0 ;
            }

        }

    }

    close(sock_fd);
    
}
 

示例:一个用户进程发送数据到内核,然后通过内核发送给另一个用户进程。

内核进程:netlink-exam-kern.c

// kernel module: netlink-exam-kern.c
#ifndef __KERNEL__
#define  __KERNEL__
#endif

#ifndef MODULE
#define  MODULE
#endif

#include 
< linux / config.h >
#include 
< linux / module.h >
#include 
< linux / netlink.h >
#include 
< linux / sched.h >
#include 
< net / sock.h >
#include 
< linux / proc_fs.h >

#define  BUF_SIZE 16384
#define  NL 30

static   struct  sock  * netlink_exam_sock;
static  unsigned  char  buffer[BUF_SIZE];
static  unsigned  int  buffer_tail  =   0 ;
static   int  exit_flag  =   0 ;

static  DECLARE_COMPLETION(exit_completion);

static   void  recv_handler( struct  sock  *  sk,  int  length)
{
        wake_up(sk
-> sk_sleep);
}


static   int  process_message_thread( void   *  data)
{
        
struct  sk_buff  *  skb  =  NULL;
        
struct  nlmsghdr  *  nlhdr  =  NULL;
        
int  len;
        DEFINE_WAIT(wait);

        daemonize(
" mynetlink " );

        
while  (exit_flag  ==   0 )  {
                prepare_to_wait(netlink_exam_sock
-> sk_sleep,  & wait, TASK_INTERRUPTIBLE);
                schedule();
                finish_wait(netlink_exam_sock
-> sk_sleep,  & wait);

                
while  ((skb  =  skb_dequeue( & netlink_exam_sock -> sk_receive_queue))
                         
!=  NULL)  {
                        nlhdr 
=  ( struct  nlmsghdr  * )skb -> data;
                        
if  (nlhdr -> nlmsg_len  <   sizeof ( struct  nlmsghdr))  {
                                printk(
" Corrupt netlink message. " );
                                
continue ;
                        }

                        len 
=  nlhdr -> nlmsg_len  -  NLMSG_LENGTH( 0 );
                        
if  (len  +  buffer_tail  >  BUF_SIZE)  {
                                printk(
" netlink buffer is full. " );
                        }

                        
else   {
                                memcpy(buffer 
+  buffer_tail, NLMSG_DATA(nlhdr), len);
                                buffer_tail 
+=  len;
                        }

                        nlhdr
-> nlmsg_pid  =   0 ;
                        nlhdr
-> nlmsg_flags  =   0 ;
                        NETLINK_CB(skb).pid 
=   0 ;
                        NETLINK_CB(skb).dst_pid 
=   0 ;
                        NETLINK_CB(skb).dst_group 
=   1 ;
                        netlink_broadcast(netlink_exam_sock, skb, 
0 ,  1 , GFP_KERNEL);
                }

        }

        complete(
& exit_completion);
        
return   0 ;
}


static   int  netlink_exam_readproc( char   * page,  char   ** start, off_t off,
                          
int  count,  int   * eof,  void   * data)
{
        
int  len;

        
if  (off  >=  buffer_tail)  {
                
*  eof  =   1 ;
                
return   0 ;
        }

        
else   {
                len 
=  count;
                
if  (count  >  PAGE_SIZE)  {
                        len 
=  PAGE_SIZE;
                }

                
if  (len  >  buffer_tail  -  off)  {
                        len 
=  buffer_tail  -  off;
                }

                memcpy(page, buffer 
+  off, len);
                
* start  =  page;
                
return  len;
        }


}


static   int  __init netlink_exam_init( void )
{
        netlink_exam_sock 
=  netlink_kernel_create(NL,  0 , recv_handler, THIS_MODULE);
        
if  ( ! netlink_exam_sock)  {
                printk(
" Fail to create netlink socket. " );
                
return   1 ;
        }

        kernel_thread(process_message_thread, NULL, CLONE_KERNEL);
        create_proc_read_entry(
" netlink_exam_buffer " ,  0444 , NULL, netlink_exam_readproc,  0 );
        
return   0 ;
}


static   void  __exit netlink_exam_exit( void )
{
        exit_flag 
=   1 ;
        wake_up(netlink_exam_sock
-> sk_sleep);
        wait_for_completion(
& exit_completion);
        sock_release(netlink_exam_sock
-> sk_socket);
}


module_init(netlink_exam_init);
module_exit(netlink_exam_exit);
MODULE_LICENSE(
" GPL " );

编译成模块:

ifneq ($(KERNELRELEASE),)
debug
- objs : =  netlink - exam - kern.o
obj
- m : =  netlink - exam - kern1.o
CFLAGS 
+=   - w  - Wimplicit - function - declaration
else
PWD :
=  $(shell pwd)
KVER 
?=  $(shell uname  - r)
KDIR :
=   / lib / modules / $(KVER) / build
all:
        $(MAKE) 
- C $(KDIR) M = $(PWD)
clean:
        rm 
- rf . * .cmd  * .o  * .mod.c  * .ko .tmp_versions
endif

用户发送进程:netlink-exam-user-send.c

// application sender: netlink-exam-user-send.c
#include  < stdio.h >
#include 
< stdlib.h >
#include 
< unistd.h >
#include 
< string .h >
#include 
< sys / types.h >
#include 
< sys / socket.h >
#include 
< linux / netlink.h >

#define  MAX_MSGSIZE 1024


int  main( int  argc,  char   *  argv[])
{
        FILE 
*  fp;
        
struct  sockaddr_nl saddr, daddr;
        
struct  nlmsghdr  * nlhdr  =  NULL;
        
struct  msghdr msg;
        
struct  iovec iov;
        
int  sd;
        
char  text_line[MAX_MSGSIZE];
        
int  ret  =   - 1 ;

        
if  (argc  <   2 )  {
                printf(
" Usage: %s atextfilename " , argv[ 0 ]);
                exit(
1 );
        }


        
if  ((fp  =  fopen(argv[ 1 ],  " r " ))  ==  NULL)  {
                printf(
" File %s dosen't exist. " );
                exit(
1 );
        }


        sd 
=  socket(AF_NETLINK, SOCK_RAW,  30 );
        memset(
& saddr,  0 ,  sizeof (saddr));
        memset(
& daddr,  0 ,  sizeof (daddr));

        saddr.nl_family 
=  AF_NETLINK;
        saddr.nl_pid 
=  getpid();
        saddr.nl_groups 
=   0 ;
        bind(sd, (
struct  sockaddr * ) & saddr,  sizeof (saddr));

        daddr.nl_family 
=  AF_NETLINK;
        daddr.nl_pid 
=   0 ;
        daddr.nl_groups 
=   0 ;

        nlhdr 
=  ( struct  nlmsghdr  * )malloc(NLMSG_SPACE(MAX_MSGSIZE));

        
while  (fgets(text_line, MAX_MSGSIZE, fp))  {
                memcpy(NLMSG_DATA(nlhdr), text_line, strlen(text_line));
                memset(
& msg,  0  , sizeof ( struct  msghdr));

                nlhdr
-> nlmsg_len  =  NLMSG_LENGTH(strlen(text_line));
                nlhdr
-> nlmsg_pid  =  getpid();   /*  self pid  */
                nlhdr
-> nlmsg_flags  =   0 ;

                iov.iov_base 
=  ( void   * )nlhdr;
                iov.iov_len 
=  nlhdr -> nlmsg_len;
                msg.msg_name 
=  ( void   * ) & daddr;
                msg.msg_namelen 
=   sizeof (daddr);
                msg.msg_iov 
=   & iov;
                msg.msg_iovlen 
=   1 ;
                ret 
=  sendmsg(sd,  & msg,  0 );
                
if  (ret  ==   - 1 )  {
                        perror(
" sendmsg error: " );
                }

        }


        close(sd);
        
return   0 ;
}

用户接收进程:netlink-exam-user-recv.c

// application sender: netlink-exam-user-send.c
#include  < stdio.h >
#include 
< stdlib.h >
#include 
< unistd.h >
#include 
< string .h >
#include 
< sys / types.h >
#include 
< sys / socket.h >
#include 
< linux / netlink.h >

#define  MAX_MSGSIZE 1024


int  main( int  argc,  char   *  argv[])
{
        FILE 
*  fp;
        
struct  sockaddr_nl saddr, daddr;
        
struct  nlmsghdr  * nlhdr  =  NULL;
        
struct  msghdr msg;
        
struct  iovec iov;
        
int  sd;
        
char  text_line[MAX_MSGSIZE];
        
int  ret  =   - 1 ;

        
if  (argc  <   2 )  {
                printf(
" Usage: %s atextfilename " , argv[ 0 ]);
                exit(
1 );
        }


        
if  ((fp  =  fopen(argv[ 1 ],  " r " ))  ==  NULL)  {
                printf(
" File %s dosen't exist. " );
                exit(
1 );
        }


        sd 
=  socket(AF_NETLINK, SOCK_RAW,  30 );
        memset(
& saddr,  0 ,  sizeof (saddr));
        memset(
& daddr,  0 ,  sizeof (daddr));

        saddr.nl_family 
=  AF_NETLINK;
        saddr.nl_pid 
=  getpid();
        saddr.nl_groups 
=   0 ;
        bind(sd, (
struct  sockaddr * ) & saddr,  sizeof (saddr));

        daddr.nl_family 
=  AF_NETLINK;
        daddr.nl_pid 
=   0 ;
        daddr.nl_groups 
=   0 ;

        nlhdr 
=  ( struct  nlmsghdr  * )malloc(NLMSG_SPACE(MAX_MSGSIZE));

        
while  (fgets(text_line, MAX_MSGSIZE, fp))  {
                memcpy(NLMSG_DATA(nlhdr), text_line, strlen(text_line));
                memset(
& msg,  0  , sizeof ( struct  msghdr));

                nlhdr
-> nlmsg_len  =  NLMSG_LENGTH(strlen(text_line));
                nlhdr
-> nlmsg_pid  =  getpid();   /*  self pid  */
                nlhdr
-> nlmsg_flags  =   0 ;

                iov.iov_base 
=  ( void   * )nlhdr;
                iov.iov_len 
=  nlhdr -> nlmsg_len;
                msg.msg_name 
=  ( void   * ) & daddr;
                msg.msg_namelen 
=   sizeof (daddr);
                msg.msg_iov 
=   & iov;
                msg.msg_iovlen 
=   1 ;
                ret 
=  sendmsg(sd,  & msg,  0 );
                
if  (ret  ==   - 1 )  {
                        perror(
" sendmsg error: " );
                }

        }


        close(sd);
        
return   0 ;
}

from:http://blog.youkuaiyun.com/dipperkun/archive/2007/12/19/1953526.aspx

Linux内核通信的Netlink机制与编程 Netlink机制提供了一种可靠的、高效的通信方式,用于实现内核与用户空间进程之间的数据交换。Netlink机制是Linux内核中用于进程间通信的一种机制,它提供了一种可靠的、高效的通信方式,用于内核与用户空间进程之间的数据交换。在本文中,我们将详细介绍Netlink机制的原理和编程方法,并给出相应的源代码示例。通过使用Netlink机制,我们可以实现内核与用户空间进程之间的高效通信。下面是一个简单的Netlink编程示例,演示了如何使用Netlink发送消息并接收回复。一、Netlink机制的原理。 阅读详情

相关推荐

linux下使用netlink获取gateway的IP地址

要在linux下的程序中获取gateway的IP地址,使用netlink是一种直接、可靠的方法,不需要依赖其它命令,直接从linux内核获取信息,netlink编程的中文资料很少,本文试图用尽可能简单的方式讨论使用netlink获取gataway的IP地址的编程方法,并有大量篇幅介绍netlink的相关数据结构和编程方法,假定阅读本文的读者对linux下编程有一定了解,具备一定的C语言能力,熟悉IPv4的socket编程。

whowin 953

Linux Netlink 代码示例

netlink 编码示例

咸鱼弟的博客 1736

linux netlink 示例代码

eunetlink.c -用户程序源码 eknetlink.c -内核程序源码 netlink提供了一种很好很强大的的用户与内核之间的通讯机制,本文通过静态的新增一个netlink协议类型,并使用这个新的netlink类型实现用户态和内核态的双向通讯,对linux的netlink通讯方式有了一个初步的认识。 说明:本文所含代码的运行环境为 android提供的 goldfish 模拟器平台, Linux 内核版本为 2.6.29

netlink实现与使用方法详解(用户态/内核态)

一、什么是netlink Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。 在Linux 内核中,使用netlink 进行应用与内核通信的应用有很多,如 路由 daemon(NETLINK_ROUTE) 用户态 socket 协议(NETLINK_USERSOCK) 防火墙(NETLINK_FIREWALL) netfilter 子系统(NETLINK_NETFILTER) 内核事件向用户态通知(NETLINK_KOBJECT

weixin_42238049的博客 1万+

BPMN-JS :修改节点“Change Type”事件类型

修改路径:node_modules\bpmn-js\lib\features\replace\ReplaceOptions.js。

TaylorY的博客 678

机器学习 -- 信用卡评分模型 -- 互联网金融风控

互联网金融主要分为资金类和资产类。资金类主要是理财产品,吸储,主要指标是用户转化、留存和复投,重在客户运营。资产类主要是贷款,包括消费金融和现金贷,小额贷款属于此类,主要目的是用户转化,还款和风险控制,信用卡评分模型就属于风险控制。 信用评分作用是对贷款申请人(信用卡申请人)做风险评估分值的方法。 信用卡评分是以大量数据的统计结果为基础,根据客户提供的资料和历史数据对客户的信用进行评估,评分卡模型...

XiaoMaEr66的博客 2419

linux netlink 机制,Linux Netlink 编程

Netlink 是内核与用户空间进程通信的一种机制,采用与 UDP socket 非常类似的编程风格。(关于 UDP socket 编程,请看这里)与 UDP 类似,Netlink 通信也有服务器端和客户端。例如,Linux 内核作为服务器端,已经运行在那里。我们则编写 Netlink 客户端,给内核发消息,并获得我们想要的信息。例子 1通过 Netlink,从内核中得到所有网口的名字。link...

weixin_39713686的博客 624

UFS 功能描述:UFS boot

UFS 启动过程介绍:启动配置,启动代码下载过程和安全性

m0_51720747的博客 1601

netlink怎么读_linux下wifi编程(基于netlink和nl80211.h)

写用户空间程序时,现在官方推荐的唯一编程方式就是基于netlink的nl80211.h编程。netlink是一种linux下的用户空间和内核空间通信的方式,传输的都是一个个的帧。用户空间程序通过生成预定义好的结构帧,与内核达到传递消息的目的。nl80211.h是一个头文件,也是用户空间调用内核wifi相关功能的接口。其中定义了所有暴露给用户空间的API函数索引(不是函数本身),以及这些函数采用的参...

weixin_29658641的博客 639

Windows/Mac/Linux三系统保姆级教程:用llama.cpp将safetensors模型转gguf格式(附常见错误解决)

本文提供Windows、Mac和Linux系统下使用llama.cpp将safetensors模型转换为gguf格式的详细教程,涵盖环境配置、转换原理及常见错误解决方案。通过跨平台兼容性处理,帮助开发者高效完成模型格式转换,优化边缘计算性能。

weixin_29227425的博客 270

学Simulink——基于 Simulink 的 滑模控制(SMC)

本文详细介绍了基于Simulink的Buck变换器滑模控制(SMC)设计与实现方法。首先阐述了传统PI控制在负载突变时的不足,以及滑模控制具有强鲁棒性和快速响应的优势。通过建立Buck变换器的连续状态方程,推导了含积分项的滑模面和控制律,并采用边界层法抑制抖振。文章分步骤讲解了Simulink模型搭建过程,包括主电路、控制器实现和负载扰动模拟模块。仿真结果表明,在负载1A↔5A阶跃时,SMC控制输出电压波动仅0.08V,恢复时间0.35ms,远优于传统PI控制。同时给出了工程实践中的参数选择建议和数字实现技

amy_mhd的博客 253

linux netlink 用法,Linux下netlink编程示例

在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink套接字实现的,同时还使用 netlink 实现了 ip queue 工具,但 ip queue的使用有其局限性,不能自由地用于各种中断过程。内核的帮助文档和其他一些 Linux 相关文章都没有对 netlink套接字在中断过程和用户空间通信的应用上作详细的说明,使得很多用户对此只有一个模糊的概念...

weixin_39551103的博客 615

Unity 面试篇|(三)设计模式篇 【全面总结 | 持续更新 | 建议收藏】

设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的总结。设计模式与方法或库的使用方式不同, 你很难直接在自己的程序中套用某个设计模式。模式并不是一段特定的代码, 而是解决特定问题的一般性概念。你可以根据模式来实现符合自己程序实际所需的解决方案。常常会混淆模式和算法, 因为两者在概念上都是已知特定问题的典型解决方案。但算法总是明确定义达成特定目标所需的一系列步骤, 而模式则是对解决方案的更高层次描述。同一模式在两个不同程序中的实现代码可能会不一样。单例模式。

游戏开发小Y的博客 12万+

Unix/Linux编程:Netlink机制

什么是Netlink通信机制 Netlink是linux提供的用于内核和用户态进程之间的通信方式。 但是注意虽然Netlink主要用于用户空间和内核空间的通信,但是也能用于用户空间的两个进程通信。 只是进程间通信有其他很多方式,一般不用Netlink。除非需要用到Netlink的广播特性时。 NetLink机制是一种特殊的socket,它是Linux特有的,由于传送的消息是暂存在socket接收缓存中,并不为接受者立即处理,所以netlink是一种异步通信机制。系统调用和ioctl是同步通信机制 .

OceanStar的博客 4137

PCL 提取两片点云的非重叠部分【2025最新版】

PCL 提取两片点云的非重叠部分。博客长期更新,本文最近一次更新时间为:2025年9月1日。

点云侠的博客 36万+

UNet改进(12):融合小波变换与注意力机制的图像分割新方法

本文提出了一种改进的WaveletAttentionUNet架构,通过结合小波变换和注意力机制来增强传统UNet的多尺度特征提取能力。该网络使用分组卷积模拟小波分解,将输入通道扩展为4个子带(LL、LH、HL、HH),并通过通道注意力机制自适应加权各子带特征。网络保留了UNet的编码器-解码器结构,在关键位置集成了WaveletAttention模块。实验证明该方法在医学图像分割等任务中能更好地保持边缘细节和复杂纹理特征,同时保持计算效率。

2501_91516851的博客 758

Linux下netlink编程示例

http://www.360doc.com/content/12/0112/10/1317564_178894692.shtml 在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,同时还使用 netlink 实现了 ip queue 工具,但 ip queue 的使用有其局限性,不能自由地用于各种中断过程。内核的帮助文档和

heyustudent的专栏 1376

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

linux netlink 编程示例(二)应用层

这篇文章给出一个netlink应用层程序用例,和上一篇博客内核篇结合起来参考。内核版本:3.4.39nlclient.c/* * Description : 应用层netlink编程 * Date :20180529 * Author :mason * Mail : mrsonko@126.com * */ #include &lt;lin...

fuyuande的博客 2151

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

linux netlink 编程示例(一)内核端

Netlink是一种内核层与应用层通信的一种机制,比如说在做一个内核模块的时候,往往会需要应用层提供一些配置信息,这时候就可以使用netlink。netlink包括内内核层和应用层,内核层注册一个netlink协议,然后定义一些消息类型,之后就可以等待来自应用层的消息了。这篇博文给出一个简单的netlink内核模块使用例子,应用层会在接下来的博文中给出。内核版本:3.4.39。 不同内核版本可能带...

fuyuande的博客 2625

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

linux下wifi编程(基于netlink和nl80211.h)

http://blog.youkuaiyun.com/ljy1988123/article/details/9263983 写用户空间程序时,现在官方推荐的唯一编程方式就是基于netlink的nl80211.h编程。        netlink是一种linux下的用户空间和内核空间通信的方式,传输的都是一个个的帧。用户空间程序通过生成预定义好的结构帧,与内核达到传递消息的目的。    

Bloom and Grow 1万+

netlink 编程介绍

Linux从2.2开始支持PF_NETLINK域的通讯方式,这个方式主要的用途是在Linux的内核空间和用户空间进行通讯。目前在网络上面关于netlink编程的中文资料很少,为了促进对netlink编程的理解我编写了这篇文章,由于我对netlink的了解不是很透彻,特别是对于内核部分不是很熟悉,所以文章中肯定有很多错误的地方还请大家指正。文章分下面几个部分进行讲述 netlink 基础知识n

calculatorw的专栏 4272

netlink编程介绍

netlink 编程介绍 Linux从 2.2开始支持PF_NETLINK 域的通讯方式,这个方式主要的用途是在Linux的内核空间和用户空间进行通讯。目前在网络上面关于netlink编程的中文资料很少,为了促进对 netlink编程的理解我编写了这篇文章,由于我对netlink的了解不是很透彻,特别是对于内核部分不是很熟悉,所以文章中肯定有很多错误的地方还 请大家指正。文章分下面几个部分进行

aabb3575007的专栏 1152

netlink学习笔记(一)

最近在学习netlink相关的东西,现在还没找到特别好的书,学习的资料主要来自网络,今天主要参考以下三个:http://linux.chinaunix.net/bbs/thread-1031932-1-1.htmlhttp://prolqspace.spaces.live.com/blog/cns!7240DE3B63F5B841!939.entryhttp://enche

Macross的专栏 1万+
上一篇: 手把手教你把Vim改装成一个IDE编程环境(图文)
下一篇: netlink 编程
pulpdog
博客等级 码龄18年 1粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值