NetLinkメカニズム使用

3762 ワード

http://blog.csdn.net/sepnic/article/details/6799476
先日はAndroidでUSB-Audioのホット挿抜をどのように実現するかを研究しました.netlinkはTCP/IPで多く使われていますが、必要に応じてHDMI/USBなどのホット挿抜メッセージでも通知できます.前人はすでにこの方面に対して深い分析があって、ここは疲れませんでした.いくつかの典型的な資料は以下の通りです.
linuxの構成インターフェース-netlink原理と設計
netlinkメカニズム-システムコールの実現
netlinkメカニズム-まとめ
PF_NETLINK応用例NETLINK_KOBJECT_UEVENの具体的な実現--udev実現原理
linuxカーネルとユーザ空間通信のnetlink使用方法
以下は私が実現したUSBホット挿抜メッセージのコードです.メッセージ文字列の解析によって対応する動作を定義できます.実はこの方法は十分ではないです.良い方法は、カーネルドライブにnetlinkを使う点対点を実現することです.ケネルcreateは、netlinkサービスを作成し、ユーザー・プログラムは、netlinkサービス端末を指定するメッセージを受信することができます.
[cpp]view play copy print?
ヽoo.ツ   
  • 〓〓include   
  • ヽoo.ツ   
  • 〓〓include   
  • ヽoo.ツ   
  •   
  • 同前 UEVEN_BUFER_SIZE 2048  
  •   
  • 要点 スリーロード.netlink()  
  • {  
  •     struct sockaddrunl client;  
  •     struct timeval tv;  
  •     要点 skfd、 rvlen ret;  
  •     fduset fds;  
  •     要点 ブffersize = 1024;  
  •   
  •     skfd = socket(AFUNETLINK、 SOCKガラ、 NETLINKKOBJECTUEVEN;  
  •     memset(&client) 0, サイゼフ(client)          
  •     client.nlfamily = AFUNETLINK  
  •     client.nl upld = get pid()   
  •     client.nlugroup = 1; /* receive broadcast メッセージ*/      
  •     set sockopt(skfd、 SOL SOCKET、 SO RCVBUF、 &バffersize、 シゼファ(buffersize)  
  •     ビッド(skfd) (struct sockaddr*&client、 サイゼフ(client)  
  •   
  •     while (1) {  
  •         char buf[UEVERNTUBUFFERUSIZE] = { 0 };  
  •           
  •         FDZERO(&fds)  
  •         FD SET(skfd) &fds);  
  •         tv.tv.usec = 0;  
  •         tv.tv.Uusec = 100 * 1000;  
  •         ret = select(skfd) + 1, &fds、 NULL NULL &tv)  
  •         if(ret) < 0)   
  •             contine;  
  •         if(!(ret) > 0 && FD(uISSET) &fds))  
  •             contine;  
  •               
  •         /* receive ダタ */   
  •         rvlen = recv(skfd) &buf、 sizeof(buf) 0)  
  •         if (rcvlen > 0) {  
  •             printf(「%s」、 buf)  
  •             // ド something here  
  •             //  
  •             //  
  •             //  
  •         }  
  •     }    
  •   
  •     close(skyfd)  
  •     return 0;  
  • )  
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <linux/netlink.h>
    
    #define UEVENT_BUFFER_SIZE 2048
    
    int thread_net_link()
    {
    	struct sockaddr_nl client;
    	struct timeval tv;
    	int skfd, rcvlen, ret;
    	fd_set fds;
    	int buffersize = 1024;
    
    	skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
    	memset(&client, 0, sizeof(client)); 	   
    	client.nl_family = AF_NETLINK;
    	client.nl_pid = getpid(); 
    	client.nl_groups = 1; /* receive broadcast message*/	
    	setsockopt(skfd, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
    	bind(skfd, (struct sockaddr*)&client, sizeof(client));
    
    	while (1) {
    		char buf[UEVENT_BUFFER_SIZE] = { 0 };
    		
    		FD_ZERO(&fds);
    		FD_SET(skfd, &fds);
    		tv.tv_sec = 0;
    		tv.tv_usec = 100 * 1000;
    		ret = select(skfd + 1, &fds, NULL, NULL, &tv);
    		if(ret < 0) 
    			continue;
    		if(!(ret > 0 && FD_ISSET(skfd, &fds)))
    			continue;
    			
    		/* receive data */ 
    		rcvlen = recv(skfd, &buf, sizeof(buf), 0);
    		if (rcvlen > 0) {
    			printf("%s
    ", buf); // do something here!!! // // // } } close(skfd); return 0; }