搶先式多執行緒網路蜘蛛 (轉)
搶先式多執行緒蜘蛛
作者:Sim Ayers 翻譯:劉建強
支援搶先式多執行緒網路,這是編寫MFC網路蜘蛛非常有用的地方。SPR工程()是一個如何用搶先式多執行緒技術實現在網上用網路蜘蛛/機器人聚集資訊的程式。
該工程產生一個象蜘蛛一樣行動的程式,該程式為斷開的URL連結檢查站點。連結驗證僅在href指定的連結上進行。它在一列表檢視CListView中顯示不斷的URL列表,以反映超連結的狀態。本工程能用作收集、資訊的模板,該模板將這些資訊存入到可以用於查詢的中。
搜尋引擎在WEB上使用叫作Robots(也叫爬蟲,蜘蛛,,漫步者,滑行者等等)的程式收集資訊,它從WEB上自動地聚集和索引資訊,接著將這些資訊存入資料庫。(注意:一個機器人將搜尋一個頁面,然後把這個頁面上的連結作為將要索引的新的URL的起點)可建立查詢去查詢這些資料庫以發現他們需要的資訊。
透過搶先式多執行緒地使用,你能索引一個基於URL連結的WEB頁面,啟動一個新的執行緒跟隨每個新的URL連結,索引一個新的URL起點。本工程使用和自定義的MDI子一起使用的MDI 文件類,在WEB頁面時顯示一個編輯檢視,在檢查URL連線時顯示一個列表檢視。另外,本工程使用了CObArray,CInteSession,CHttpConnection,ChttpFile和CWinThread MFC類。CWinThread類用於產生多執行緒來代替在CInternetSession類中的非同步,這種模式是從insock的16位平臺保留下來的。SPIDER工程使用簡單的工作執行緒去檢查URL連結,或者下載一個Web頁面。CSpiderThread類是從CWinThread類中派生的,所以,每個CSpiderThread可以使用CWinThread 的MESSAGE_MAP()。透過在CSpiderThread類中宣告"DECLARE_MESSAGE_MAP()",使用者介面可以響應使用者的輸入。這意味著你可以在一個Web上檢查URL連結的同時,你可以從另一個Web伺服器上下載或開啟一個Web頁面。只有線上程數超過定義為64的MAXIMUM_WAIT_S時,使用者介面將不會響應使用者的輸入。在每個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;
D m_dwServiceType;
DWORD m_threadID;
DWORD m_Status;
URLStatus m_pStatus;
INTERNET_PORT m_nPort;
int m_type;
BOOL m_Links;
}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檔案的請求的日誌。你或許會收到來自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
問題:
允許 32,767 個URL 連結在 CListView 中。
不能分析 URL的正確性 。
資料:
Internet tools - Fred Forester
Multithreading Applications in Win32
Win32 Multithreaded Programming
中華技術網整理釋出 http://www.aocus.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988632/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 多執行緒搶沙包遊戲執行緒遊戲
- Java 多執行緒基礎(十一)執行緒優先順序和守護執行緒Java執行緒
- 【java】【多執行緒】睡眠/守護/加入/禮讓執行緒,執行緒優先順序(4)Java執行緒
- 多執行緒-執行緒排程及獲取和設定執行緒優先順序執行緒
- 多執行緒常用函式執行緒函式
- iOS 多網路請求的執行緒安全iOS執行緒
- .NET多執行緒程式設計(1):多工和多執行緒 (轉)執行緒程式設計
- 關於多執行緒(轉)執行緒
- 多執行緒和多執行緒同步執行緒
- 多優先順序執行緒池實踐執行緒
- 程式設計思想之多執行緒與多程式(2):執行緒優先順序與執行緒安全程式設計執行緒
- 多執行緒【執行緒池】執行緒
- 多執行緒--執行緒管理執行緒
- Java多執行緒——執行緒Java執行緒
- 執行緒與多執行緒執行緒
- .NET多執行緒程式設計(3):執行緒同步 (轉)執行緒程式設計
- VC多執行緒 C++ 多執行緒執行緒C++
- 多執行緒-執行緒控制之休眠執行緒執行緒
- 多執行緒-執行緒控制之加入執行緒執行緒
- 多執行緒-執行緒控制之禮讓執行緒執行緒
- 多執行緒-執行緒控制之中斷執行緒執行緒
- 多執行緒程式設計(轉)執行緒程式設計
- 多執行緒學習初步(轉)執行緒
- 玩轉java多執行緒 之多執行緒基礎 執行緒狀態 及執行緒停止實戰Java執行緒
- 多執行緒之初識執行緒執行緒
- Java多執行緒-執行緒中止Java執行緒
- Java多執行緒——執行緒池Java執行緒
- 多執行緒-執行緒概述等執行緒
- 多執行緒系列(1),多執行緒基礎執行緒
- 多執行緒系列(二):多執行緒基礎執行緒
- boost中asio網路庫多執行緒併發處理實現,以及asio在多執行緒模型中執行緒的排程情況和執行緒安全。執行緒模型
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 多執行緒安全strtok函式MStrTok執行緒函式
- 多執行緒-執行緒控制之守護執行緒執行緒
- a、多執行緒執行緒
- 掃描整個網段的多執行緒程式(轉)執行緒
- java 多執行緒守護執行緒Java執行緒
- Java多執行緒-執行緒通訊Java執行緒