Android 4.1 Netd詳細分析(三)程式碼分析1

來源:互聯網
上載者:User

 

個人郵箱:xiaokeweng@gmail.com

 

 

       接下來開始從程式碼分析,按照從下至上的順序來分析,從native層向framework層過渡,Android的各個層之間嚴格按照軟體工程原理的低耦合要求,關於Android 的系統架構可以參考附錄:link~(待完善)

       在Netd部分使用到得Socket通訊,關於Android內部的IPC機制可以參考附錄:link~(待完善)

===================================================================

#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <errno.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <fcntl.h>#include <dirent.h>#define LOG_TAG "Netd"#include "cutils/log.h"#include "CommandListener.h"#include "NetlinkManager.h"#include "DnsProxyListener.h"#include "MDnsSdListener.h"static void coldboot(const char *path);static void sigchld_handler(int sig);static void blockSigpipe();int main() {/*********************************************************以下兩個為函數主要使用的類*CommandListener :監聽 framework 層的命令,並調用本類中註冊的處理函數,並將處理結果返回*NetLinkManager  :管理 kernel 層相關的 event,將收到收到的資訊提交給 framework 層********************************************************/    CommandListener *cl;    NetlinkManager *nm;/********************************************************* 這兩個可以各自理解為單獨的工作模組,相對上面的類更加簡單。* DnsProxyListener :DNS 解析,通過系統庫函數 getaddrinfo,並將解析結果反饋給 framework 層* MDnsSdListener   :Muliticast-DNS Server Descript 利用區域網路其他對象解析********************************************************/    DnsProxyListener *dpl;    MDnsSdListener *mdnsl;    ALOGI("Netd 1.0 starting");//  signal(SIGCHLD, sigchld_handler);    blockSigpipe();//禁用Sigpipe    if (!(nm = NetlinkManager::Instance())) {//執行個體化nm        ALOGE("Unable to create NetlinkManager");        exit(1);    };/******************************************************** nm->setBroadcaster((SocketListener *) cl)* setBroadcaster函數將NetlinkManager的成員變數mBroadcaster設定成cl,這兩個變數都是* ScoketListener的指標類型,命令執行廣播函數,就會調用這個SocketListener的指標來調用* SocketListener類的廣播函數* 因為:繼承關係:* CommandListener(子類)-->FrameworkListener()-->SocketListener(父類)*******************************************************/     cl = new CommandListener();//執行個體化cl    nm->setBroadcaster((SocketListener *) cl);//關聯nm和cl這樣nm就可以通過方法//廣播訊息來回複給framework/*************************************************** 使用了 Netlink socket 是用於實現使用者進程與核心進程通訊的 IPC,* 下面的 start()就是開啟監聽核心的線程。*************************************************/  if (nm->start()) { ALOGE("Unable to start NetlinkManager (%s)", strerror(errno)); exit(1); }/*************************************************** 關於DnsProxyListener/MdnsSdListener會在後面單獨詳細* 各自的原理同CommandListener+NetlinkManager兩個組成的系統**************************************************/ // Set local DNS mode, to prevent bionic from proxying(自動代理) // back to this service, recursively.(遞迴) // DnsProxyListener -> FrameworkListrner -> SocketListener       setenv("ANDROID_DNS_MODE", "local", 1); //設定為本地模式,是一個全域變數    //DNS    dpl = new DnsProxyListener();    if (dpl->startListener()) {        ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));        exit(1);    }    //multicast_DNS_server_descript_listener//多播DNS守護進程//內網沒有DNS伺服器時,出現此組播    mdnsl = new MDnsSdListener();    if (mdnsl->startListener()) {        ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));        exit(1);    }/************************************************* cl 開啟線程,監聽 framework 層下發的命令,並調用相關函數處理*********************************************** */    if (cl->startListener()) {        ALOGE("Unable to start CommandListener (%s)", strerror(errno));        exit(1);    }    // 成為守護進程    while(1) {        sleep(1000);    }    ALOGI("Netd exiting");    exit(0);} ///*********打雜函數**************//// 實際還真沒看到打雜的意義/作用是什麼……static void do_coldboot(DIR *d, int lvl){    struct dirent *de;    int dfd, fd;    dfd = dirfd(d);    fd = openat(dfd, "uevent", O_WRONLY);    if(fd >= 0) {        write(fd, "add\n", 4);        close(fd);    }    while((de = readdir(d))) {        DIR *d2;        if (de->d_name[0] == '.')            continue;        if (de->d_type != DT_DIR && lvl > 0)            continue;        fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);        if(fd < 0)            continue;        d2 = fdopendir(fd);        if(d2 == 0)            close(fd);        else {            do_coldboot(d2, lvl + 1);            closedir(d2);        }    }}static void coldboot(const char *path){    DIR *d = opendir(path);    if(d) {        do_coldboot(d, 0);        closedir(d);    }}static void sigchld_handler(int sig) {    pid_t pid = wait(NULL);    ALOGD("Child process %d exited", pid);}static void blockSigpipe(){    sigset_t mask;    sigemptyset(&mask);    sigaddset(&mask, SIGPIPE);    if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)        ALOGW("WARNING: SIGPIPE not blocked\n");}

       至此,按照 main 函數的流程進行分析。

       首先如,系統的部分主幹關係圖,系統可以按照功能和相關性分為三大部分,DnsProxyLis-
tener,MDnsSdListener,和 CommandListener + NetlinkManager 三大部分,每個部分都能夠利用內
部 socket 和獨立線程,接收到 Framework 層的命令,系統叫用作業 Kernel 層,並回複 Framework 反
饋,可是說 Netd 充當了 Framework 與 kernel 的橋樑。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.