larbin源碼分析(九) NamedSite站點(diǎn)的抽象類
一 類的主要功能
NamedSite 該類為一個(gè)主站點(diǎn)的抽象類,主站點(diǎn)類似www.baidu.com.
二 類的主要成員變量
/* name of the site */
(1) char name[maxSiteSize]; 主站點(diǎn)的名稱
(2) uint16_t port; // 主站點(diǎn)的端口號(hào)
(3) uint16_t nburls; //內(nèi)存中該站點(diǎn)的所有url的數(shù)目
(4) url *fifo[maxUrlsBySite]; //內(nèi)存中該站點(diǎn)的url緩沖區(qū)隊(duì)列
(5) uint8_t inFifo; //內(nèi)存中隊(duì)列的隊(duì)首
(6)uint8_t outFifo; //內(nèi)存中隊(duì)列的尾部
(7)bool isInFifo; //該站點(diǎn)是否在dnsSite中,即已經(jīng)遍歷完畢
(8)char dnsState; //dns的狀態(tài)
(9) /** internet addr of this server */
char dnsState; //internet的網(wǎng)站地址
struct in_addr addr; //ipv4地址
uint ipHash; //iphash值
(10) time_t dnsTimeout; //請(qǐng)求dns以及獲取robots.txt的時(shí)延 * Date of expiration of dns call and robots.txt fetch */
(11)Vector<char> forbidden; /** test if a file can be fetched thanks to the robots.txt */ robots文件中禁止訪問(wèn)的url
三 成員函數(shù)
(1)NamedSite構(gòu)造函數(shù)
實(shí)質(zhì)是將上述各個(gè)成員變量進(jìn)行初始化操作。
(2)putInFifo(url *u) 將u插入進(jìn)隊(duì)列fifo中,隊(duì)列為循環(huán)隊(duì)列。
(3)url *NamedSite::getInFifo() 將fifo中的url取出隊(duì)頭
(4)int fifoLength() {(inFifo - outFifo + maxUrlsBySite) % maxUrlsBySite ;}
(5)putGenericUrl(url *u, int limit, bool prio) //將獲取的url插入進(jìn)入站點(diǎn)的fifo隊(duì)列中
//當(dāng)當(dāng)前的nburls的數(shù)量大于限制的時(shí)候,需要根據(jù)優(yōu)先級(jí)將其存儲(chǔ)在URLsPriorityWait隊(duì)列或者URLsDiskWait隊(duì)列中。
函數(shù)實(shí)現(xiàn)方法如下:
if (nburls > maxUrlsBySite-limit) { //當(dāng)前內(nèi)存中的nburls數(shù)目,已經(jīng)超過(guò)該限制了,下面就判斷是否需要忽略該URL
if (!strcmp(name, u->getHost())) { //首先判斷當(dāng)前的站點(diǎn)名稱和url的host名稱是否一致
if (dnsState == errorDns) { //如果當(dāng)前的dns請(qǐng)求狀態(tài)是 errorDns,則進(jìn)行忽略操作
nburls++;
forgetUrl(u, noDNS);
return;
}
if (dnsState == noConnDns) { //當(dāng)當(dāng)前的dns狀態(tài)為 無(wú)連接,則進(jìn)行URL忽略
nburls++;
forgetUrl(u, noConnection);
return;
}
if (u->getPort() == port //如果當(dāng)前的url在對(duì)應(yīng)網(wǎng)站的forbid列表中,則將對(duì)應(yīng)的url加入忽略
&& dnsState == doneDns && !testRobots(u->getFile())) {
nburls++;
forgetUrl(u, forbiddenRobots);
return;
}
}
//此時(shí)URL的host名稱和當(dāng)前站點(diǎn)的host地址不同,則需要記錄(此時(shí)仍然無(wú)法放入fifo隊(duì)列中,需要放入等待隊(duì)列中)
refUrl();
global::inter->getOne(); //實(shí)際上inter表示全部站點(diǎn)中,fifo隊(duì)列的數(shù)量
if (prio) {
global::URLsPriorityWait->put(u);
} else {
global::URLsDiskWait->put(u);
}
}
//此處沒(méi)有超出fifo隊(duì)列的大小限制
else {
nburls++;
if (dnsState == waitDns
|| strcmp(name, u->getHost())
|| port != u->getPort()
|| global::now > dnsTimeout) {
// dns not done or other site
putInFifo(u); //將此url放入進(jìn)fifo中
addNamedUrl(); //將namesites中的url數(shù)目增加
// Put Site in fifo if not yet in
if (!isInFifo) { //如果當(dāng)前該namesites沒(méi)在dnsites中時(shí),則進(jìn)行添加操作
isInFifo = true;
global::dnsSites->put(this);
}
} else switch (dnsState) {
case doneDns:
transfer(u);
break;
case errorDns:
forgetUrl(u, noDNS);
break;
default: // noConnDns
forgetUrl(u, noConnection);
}
}
(6)void NamedSite::newQuery () //該函數(shù),主要用于發(fā)起一個(gè)新的dns請(qǐng)求
若請(qǐng)求成功,則調(diào)用調(diào)用dnsOk()。該函數(shù)中,主要有處理代理地址,若沒(méi)有解析到dns,則需要調(diào)用adns包中的請(qǐng)求函數(shù)。
(7)void NamedSite::dnsAns (adns_answer *ans) 未看明白
(8)void NamedSite::dnsOK () { //請(qǐng)求各個(gè)站點(diǎn)的robots.txt文件
Connexion *conn = global::freeConns->get(); //從全局變量中獲取空閑鏈接
char res = getFds(conn, &addr, port); //根據(jù)addr建立連接
if (res != emptyC) {
conn->timeout = timeoutPage;
if (global::proxyAddr != NULL) {
// use a proxy
conn->request.addString("GET http://");
conn->request.addString(name);
char tmp[15];
sprintf(tmp, ":%u", port);
conn->request.addString(tmp);
conn->request.addString("/robots.txt HTTP/1.0\r\nHost: ");
} else {
// direct connection
conn->request.addString("GET /robots.txt HTTP/1.0\r\nHost: ");
}
conn->request.addString(name);
conn->request.addString(global::headersRobots); //具體請(qǐng)求報(bào)文,在global.cc中
conn->parser = new robots(this, conn); //應(yīng)該在file文件中,構(gòu)建一個(gè)解析類robots
conn->pos = 0;
conn->err = success;
conn->state = res;
} else {
// Unable to get a socket
global::freeConns->put(conn);
dnsState = noConnDns;
dnsErr();
}
}
(9)bool NamedSite::testRobots(char *file) //判斷該文件是否在robots.txt中的屏蔽列表中
(10)NamedSite::robotsResult (FetchError res) 獲取robots.txt ,然后掃描fifo隊(duì)列,
將其中與namesite類的站點(diǎn)名稱以及端口號(hào)相同的transfer到 Ipsite中,需要計(jì)算其Iphash
(11)NamedSite::transfer (url *u) 將站點(diǎn)地址copy到url中,然后判斷是否在robots.txt的列表中
若在則執(zhí)行forgetUrl,否則添加到global::IPSiteList[ipHash].putUrl(u);中。
四 綜上:
該類主要是站點(diǎn)類的抽象,涉及到了 請(qǐng)求DNS ,請(qǐng)求robots.txt ,打開(kāi)connexion中的鏈接。