Win32 API 支持抢先式多线程网络,这是编写MFC网络蜘蛛非常有用的地方。SPIDER工程(程序)是一个如何用抢先式多线程技术实现在网上用网络蜘蛛/机器人聚集信息的程序。

  该工程产生一个象蜘蛛一样行动的程序,该程序为断开的URL链接检查WEB站点。链接验证仅在href指定的链接上进行。它在一列表视图CListView中显示不断更新的URL列表,以反映超链接的状态。本工程能用作收集、索引信息的模板,该模板将这些信息存入到可以用于查询的数据库文件中。

  搜索引擎在WEB上使用叫作Robots(也叫爬虫,蜘蛛,蠕虫,漫步者,滑行者等等)的程序收集信息,它从WEB上自动地聚集和索引信息,接着将这些信息存入数据库。(注意:一个机器人将搜索一个页面,然后把这个页面上的链接作为将要索引的新的URL的起点)用户可创建查询去查询这些数据库以发现他们需要的信息。

  通过抢先式多线程地使用,你能索引一个基于URL链接的WEB页面,启动一个新的线程跟随每个新的URL链接,索引一个新的URL起点。本工程使用和自定义的MDI子框架一起使用的MDI 文档类,在下载WEB页面时显示一个编辑视图,在检查URL连接时显示一个列表视图。另外,本工程使用了CObArray,CInternetSession,CHttpConnection,ChttpFile和CWinThread MFC类。CWinThread类用于产生多线程来代替在CInternetSession类中的异步模式,这种模式是从insock的16位windows平台保留下来的。SPIDER工程使用简单的工作线程去检查URL链接,或者下载一个Web页面。CSpiderThread类是从CWinThread类中派生的,所以,每个CSpiderThread对象可以使用CWinThread 的MESSAGE_MAP()函数。通过在CSpiderThread类中声明"DECLARE_MESSAGE_MAP()",用户接口可以响应用户的输入。这意味着你可以在一个Web服务器上检查URL链接的同时,你可以从另一个Web服务器上下载或打开一个Web页面。只有在线程数超过定义为64的MAXIMUM_WAIT_OBJECTS时,用户接口将不会响应用户的输入。在每个CSpiderThread对象的构造函数中,我们提供了ThreadProc函数以及将传送到ThreadProc函数的线程参数。

  CSpiderThread* pThread;
  pThread = NULL;
  pThread = new CSpiderThread(CSpiderThread::ThreadFunc,pThreadParams); // 创建一个新的 CSpiderThread 对象;

  在类CSpiderThread 构造函数中我们在线程参数中设置指针CWinThread* m_pThread ,于是我们可以指向这个线程正确的事例:
  pThreadParams->m_pThread = this;

  The CSpiderThread ThreadProc Function

  // 简单的工作线程函数
  UINT CSpiderThread::ThreadFunc(LPVOID pParam)
  {
  ThreadParams * lpThreadParams = (ThreadParams*) pParam;
  CSpiderThread* lpThread = (CSpiderThread*) lpThreadParams->m_pThread;

  lpThread->ThreadRun(lpThreadParams);

  // 这里使用SendMessage代替PostMessageUse,以保持当前线程数同步。
  // 如果线程数大于 MAXIMUM_WAIT_OBJECTS (64), 本程序将变得不能响应用户输入

  ::SendMessage(lpThreadParams->m_hwndNotifyProgress,
  WM_USER_THREAD_DONE, 0, (LPARAM)lpThreadParams);
  // 删除lpThreadParams 和减少线程总数

  return 0;
  }

  这个结构传递给CSpiderThread ThreadProc函数
  typedef struct tagThreadParams
  {
  HWND m_hwndNotifyProgress;
  HWND m_hwndNotifyView;
  CWinThread* m_pThread;
  CString m_pszURL;
  CString m_Contents;
  CString m_strServerName;
  CString m_strObject;
  CString m_checkURLName;
  CString m_string;
  DWORD m_dwServiceType;
  DWORD m_threadID;
  DWORD m_Status;
  URLStatus m_pStatus;
  INTERNET_PORT m_nPort;
  int m_type;
  BOOL m_RootLinks;

  }ThreadParams;

  CSpiderThread对象创建后,我们用CreatThread函数开始一个新的线程对象地执行。

  if (!pThread->CreateThread()) //开始一 CWinThread 对象地执行
  {
  AfxMessageBox("Cannot Start New Thread");
  delete pThread;
  pThread = NULL;
  delete pThreadParams;
  return FALSE;
  }
  一旦新的线程正在运行,我们使用::SengMessage函数发送消息到 CDocument's-> CListView ,这个消息带有URL链接的状态结构。
  if(pThreadParams->m_hwndNotifyView != NULL)
  ::SendMessage(pThreadParams->m_hwndNotifyView,WM_USER_CHECK_DONE, 0, (LPARAM) &pThreadParams->m_pStatus);

  URL状态的结构:

  typedef struct tagURLStatus
  {
  CString m_URL;
  CString m_URLPage;
  CString m_StatusString;
  CString m_LastModified;
  CString m_ContentType;
  CString m_ContentLength;
  DWORD m_Status;
  }URLStatus, * PURLStatus;

  每个新的线程建立一个新的CMyInternetSession类(派生于CInternetSession)对象,并把 EnableStatusCallback设置为TRUE,于是,我们可以在所有的InternetSession回调时检查状态。将回调使用的dwContext ID设置为线程ID。

  BOOL CInetThread::InitServer()
  {

  try
  {
  m_pSession = new CMyInternetSession(AgentName,m_nThreadID);
  int ntimeOut = 30; // 很重要!如果设置太小回引起服务器超时,如果设置太大则回引起线程挂起。
  /*
  网络连接请求时间超时值在数毫秒级。如果连接请求时间超过这个超时值,请求将被取消。
  缺省的超时值是无限的。
  */
  m_pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,1000* ntimeOut);

  /* 在重试连接之间的等待的延时值在毫秒级。*/
  m_pSession->SetOption(INTERNET_OPTION_CONNECT_BACKOFF,1000);

  /* 在网络连接请求时的重试次数。如果一个连接企图在指定的重试次数后仍失败,则请求被取消。 缺省值为5。 */
  m_pSession->SetOption(INTERNET_OPTION_CONNECT_RETRIES,1);
  m_pSession->EnableStatusCallback(TRUE);

  }
  catch (CInternetException* pEx)
  {
  // catch errors from WinINet
  //pEx->ReportError();
  m_pSession = NULL;
  pEx->Delete();
  return FALSE ;
  }

  return TRUE;
  }

  在一个单或多线程程序中使用MFC WinIne类,关键是要在所有MFC WinInet类函数周围使用try和catch块。因为互连网有时很不稳定,或者你访问的Web页面已不存在,则这种情况下,将抛出一个CInternetException错误。

  try
  {
  // some MFC WinInet class function
  }
  catch (CInternetException* pEx)
  {
  // catch errors from WinINet
  //pEx->ReportError();
  pEx->Delete();
  return FALSE ;
  }
  最初线程数最大设置为64,你可以将它设置为从1到100的任何数。设置太高会使链接失败,意味着你将不得不重新检查URL链接。在/cgi-bin/目录下一个连续不断地迅猛地HTTP请求会使服务器崩溃。SPIDER 程序在1秒中发送四个HTTP请求,1分钟240个。这也将会使服务器崩溃。在任何服务器上你检查时放仔细一点。每个服务器都有一个请求Web文件的请求代理IP地址的日志。你或许会收到来自Web服务器管理员的龌龊的邮件。

  你可以为一些目录建立robots.txt 文件来防止这些目录被索引。这个机制通常用于保护/cgi-bin/ 目录。CGI脚本占用更多的要检索的服务器资源。当SPIDER程序检查URL链接时,它的目标是不太快地请求太多的文档。SPIDER程序坚持机器人拒绝的标准。这个标准是机器人开发者之间的协议,允许WWW站点限制URL上的机器人的请求。通过使用这个限制访问的标准,机器人将不检索Web服务器希望拒绝的任何文档。在检查根URL前,程序检查看是否有robots.txt文件在主目录下。如果SPIDER程序发现robots.txt文件,将放弃搜索。另外,程序也检查所有Web页面中的META标记。如果发现一个META标记,它的NAME="ROBOTS" CONTENT ="NOINDEX,NOFOLLOW",则不索引那个页面上的URL。

  创建:
  Windows 95
  MFC/VC++ 5.0
  WinInet.h 时间 9/25/97
  WinInet.lib 时间 9/16/97
  WinInet.dll 时间 9/18/97

抢先式多线程网络蜘蛛相关推荐

  1. Java网络蜘蛛/网络爬虫 Spiderman

    Spiderman - 又一个Java网络蜘蛛/爬虫 Spiderman 是一个基于微内核+插件式架构的网络蜘蛛,它的目标是通过简单的方法就能将复杂的目标网页信息抓取并解析为自己所需要的业务数据. 主 ...

  2. 用C#2.0实现网络蜘蛛(WebSpider)

    摘要:本文讨论了如何使用C#2.0实现抓取网络资源的网络蜘蛛.使用这个程序,可以通过一个入口网址(如http: //www.comprg.com.cn)来扫描整个互联网的网址,并将这些扫描到的网址所指 ...

  3. NetSpider 网络蜘蛛1.0 的简介

    NetSpider 网络蜘蛛1.0 的简介 支持多线程下载和 自动断点续传.特别适合对网站上的图象文件进行自动下载,是图片 搜集者的利器.详细的使用说明见: 网络蜘蛛是一个自动搜索HTML页面并下载指 ...

  4. “抢先式多任务”“协同式多任务”

    在"多任务"一文中,我们提到了"协同式多任务"与"抢先式多任务"的概念和二者的区别,谈到现在主流的多任务实现是"抢先式多任务&qu ...

  5. day16多线程网络编程日志枚举

    多线程&网络编程 一.实现多线程 1.1 相关概念 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的一条执行路径.实际运作单位.简单理解:应用软件中互相独立,可以同时运 ...

  6. Linux C实现用户态协作式多线程!

    皮鞋?湿,不会胖,下雨也不怕!但皮鞋老板不让老湿说协程,那老湿就不说了,毕竟也真的不懂. 前天半夜写下一篇文章作为对九年前一个疑问的回应: Linux C实现纯用户态抢占式多线程!: https:// ...

  7. Blue Spider网络蜘蛛软件

    1.Blue Spider网络蜘蛛软件 2.软件简称: 3.版本号:v1.0 4.分类号:67500-9100 5.首次发表地点:西安 6.硬件环境:PC机(内存1G以上) 7.软件环境:Window ...

  8. [转]用 C 语言编写一个网络蜘蛛

    用 C 语言编写一个网络蜘蛛来搜索网上出现的电子邮件地址 作者:zhoulifa 来源:http://bbs.chinaunix.net/viewthread.php?tid=821361 可能大家经 ...

  9. 网络蜘蛛Spider 工作原理

    网络蜘蛛 Web spider (或称 Crawler)是一种能够跟踪网络上超链接结构,并不断进行网络资源发现与采集的程序.作为搜索引擎的资源采集部分,Web  Spider的性能将直接影响到整个搜索 ...

  10. 单线程与多线程网络程序架构简介

    文章目录 1 单线程与多线程网络程序架构简介 1.1 服务端单线程处理多客户端 1.2 服务端多进程多端口处理多客户端 1.3 服务端多线程单端口分组处理多客户端 1.4 服务端多线程多端口分组处理多 ...

最新文章

  1. 用质因子去分解质因数
  2. linux ubuntu 虚拟机中配置samba的实现文件共享的方法
  3. Redis面试常见问题与详解
  4. java线程的基本概念
  5. Good Technology 产品特色
  6. 学习笔记(41):Python实战编程-按钮
  7. Iptables入门教程
  8. 配置java编译环境
  9. 使用FreeImage加载纹理
  10. Spring Cloud 入门 之 Zuul 篇(五)
  11. 1.1.29 加入项目符号后换行文字未对齐
  12. NodeJs——(14)express框架的send()方法简介
  13. Javascript项目
  14. C51系列单片最小机原理图及L298N接线图
  15. xmind8 破解激活教程
  16. 节假日查询接口,加班,补班,日期查询,放假,日历
  17. PHP手册 2009国庆版
  18. 小白看了直呼细节--CPP“引用”
  19. (转)80后生存法则
  20. 2021年4月总结5月计划

热门文章

  1. 绿盾加密软件怎么暂停_天锐绿盾加密软件 应用程序限制 网络端口限制 流量限制...
  2. 如何下载全国的POI数据,如何获取全国的POI数据,poi数据搜索,高德poi获取,poi数据分析,poi免费数据,城市规划数据
  3. Win10系统字体太小的调整设置教程
  4. 大数据做基础 构建流动人口健康屏障
  5. 哲理故事300篇(中)
  6. 群晖nas存储系统原理_群晖NAS入门教程第四节:群晖存储空间管理员功能和磁盘阵列类型的简介...
  7. 上海车展自动驾驶产业链盘点
  8. ArcView GIS 应用与开发技术(1)-ViewTheme
  9. java压缩图片工具类Thumbnailator
  10. API接口文档生成方案调研