Larbin 搜索引擎源码赏析——(四)后台控制爬虫的接口,一个极为简单的telnet服务器

 头文件 input.h

 

 // Larbin // Sebastien Ailleret // 03-02-00 -> 03-02-00 #ifndef INPUT_H #define INPUT_H #include "global.h" /** Entry point from the outside */ void *startInput (void *none); #endif // INPUT_H

 

 

 

 

具体实现文件 input.cc

 

// Larbin // Sebastien Ailleret // 03-02-00 -> 03-02-00 #include #include #include #include "types.h" #include "xutils/text.h" #include "xinterf/input.h" #include "xutils/debug.h" static void manageConnection (int fds); /** The way to submit something to fetch * @param urlDoc the Url of the page to fetch */ ////////////////////////////////////////////////////////////////// // //函数功能:提供telnet连接的服务,实现通过telnet协议远程向爬虫添加新的url的功能 //参数:void *none 不传递任何有意义的函数 //返回值:void * 返回NULL // /////////////////////////////////////////////////////////////////// void *startInput (void *none) { crash("Input is waiting for queries"); int fds; int nAllowReuse = 1; struct sockaddr_in addr; bzero (&addr, sizeof(addr)); //置零操作。 //创建套接字建立网络连接 addr.sin_addr.s_addr = INADDR_ANY; addr.sin_family = AF_INET; addr.sin_port = htons(global::inputPort); //向Larbin添加url等输入信息的telnet接口 if ((fds = socket(AF_INET, SOCK_STREAM, 0)) == -1 || setsockopt(fds, SOL_SOCKET, SO_REUSEADDR, (char*)&nAllowReuse, sizeof(nAllowReuse)) || bind(fds, (struct sockaddr *) &addr, sizeof(addr)) != 0 || listen(fds, 4) != 0) { cerr << "Unable to get the socket/n"; exit(1); }//end if // manage requests for (;;) { struct sockaddr_in addrc; int fdc; uint len = sizeof(addr); //接收网络中的连接请求 fdc = accept(fds, (struct sockaddr *) &addrc, &len); if (fdc == -1) { //新的连接的套接字出现问题 cerr << "Trouble with startInput.../n"; } else { //调用处理连接的函数 manageConnection(fdc); }//end if_else }//end for // Needed by startThread return NULL; } /** read all urls from this socket * The first line gives the status ("priority:1 deapth:3 test:0") */ ///////////////////////////////////////////////////////////////////////////// // //函数功能:通过解析接收到的数据,将新增的url信息,添加到爬虫中 //参数:int fds 套接字变量 //返回值:void 无返回值 //注:这里为什么用静态函数呢,还不清楚:保证了该函数在其它一个文件中是不可见。 // 除了input.cc文件 // test标识的作用,判断是否需要检测,该url是否爬虫已经爬过,如果设为0,则不需要 // 检测,否则需要检测。 ///////////////////////////////////////////////////////////////////////////// static void manageConnection (int fds) { // Get status line char *line = noEndReadline(fds); //在text.h中定义,从网络中读取一行数据 if (line != NULL) { uint priority; uint deapth; uint test; if (sscanf(line, "priority:%u deapth:%u test:%u", //提取优先级,挖掘深度等信息。 &priority, &deapth, &test) == 3) { // The first line is valid delete [] line; // Get urls line = noEndReadline(fds); //读取相关的url信息 while (line != NULL) { url *u = new url(line, deapth); if (u->isValid()) { if (test) { //如果test==1,则需要通过hash表检测,是否已经爬取过该url if (global::seen->testSet(u)) //是一个hash表的类,在global.h文件中进行定义 static hashTable *seen; { if (priority) { //如果prrority==1 即优先级为1 ,优先级比较高 global::URLsInput->put(u); } else { //低优先级 global::URLsInternal->put(u); }//end if(priority) } else { delete u; }//end if (global::seen->testSet(u)) } else { //不做检测的情况 global::seen->set(u); //将当前的url信息,写入hash表中,以避免以后重复爬去 if (priority) //根据优先级,将url添加到不同的队列中去。 { global::URLsInput->put(u); } else { global::URLsInternal->put(u); }//end if (priority) }//end if (test) } else { delete u; }//end if (u->isValid()) line = noEndReadline(fds); //读取下一个url信息 }//end while (line != NULL) } else { cerr << "The first line of input is not valid... Connection closed/n"; }//end if (sscanf(line, "priority:%u deapth:%u test:%u", }//if (line != NULL) // close the socket //关闭套接字 shutdown(fds, 2); close(fds); }

你可能感兴趣的:(源码赏析)