Download.cpp
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:24k
源码类别:

P2P编程

开发平台:

Visual C++

  1. // Download.cpp: implementation of the CDownload class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "testBT.h"
  6. #include "Download.h"
  7. #include "val.h"
  8. #include "FileTorrent.h"
  9. #include "Storage.h"
  10. #include "StorageWrapper.h"
  11. #include "Rerequester.h"
  12. #include "RawServer.h"
  13. #include "Encrypter.h"
  14. #include "Connector.h"
  15. #include "PiecePicker.h"
  16. #include "RateMeasure.h"
  17. #include "Downloader.h"
  18. #include "Upload.h"
  19. #include "choker.h"
  20. #include "DownloaderFeedback.h"
  21. #include "SetupRegister.h"
  22. #include "FileDB.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char THIS_FILE[]=__FILE__;
  26. #define new DEBUG_NEW
  27. #endif
  28. //////////////////////////////////////////////////////////////////////
  29. // Construction/Destruction
  30. //////////////////////////////////////////////////////////////////////
  31. void SingleDownloadTest();
  32. CDownload::CDownload()
  33. {
  34. m_bCheckHash = true;
  35. m_hevUnPause =  CreateEvent(0, true, true, 0);
  36. m_hThreadDone = CreateEvent(0, true, true, 0);
  37. m_hevDone = CreateEvent(0, true, false, 0);
  38. m_hCompleted = CreateEvent(0, true, false, 0);
  39. m_hThreadSafe = CreateEvent(0, true, false, 0);
  40. m_pdownloader = 0;
  41. m_pconncetorget = 0;
  42. m_pRequester = 0;
  43. m_pChoker = 0;
  44. m_pEncrypter = 0;
  45. GetSetupParameter();
  46. long ltime = 0;
  47. time(&ltime);
  48. srand(ltime);
  49. m_bClosing = false;
  50. }
  51. CDownload::~CDownload()
  52. {
  53. Close();
  54. assert(IsEventSet(m_hThreadDone));
  55. CloseHandle(m_hevDone);
  56. CloseHandle(m_hCompleted);
  57. CloseHandle(m_hThreadDone);
  58. CloseHandle(m_hThreadSafe);
  59. }
  60. void CDownload::GetSetupParameter()
  61. {
  62. g_defaults["max_uploads"] = _variant_t(4L); //the maximum number of uploads to allow at once.
  63. g_defaults["keepalive_interval"] = _variant_t(120L); //number of seconds to pause between sending keepalives
  64. g_defaults["download_slice_size"] = _variant_t(pow(2, 14)); //How many bytes to query for per request.
  65. g_defaults["request_backlog"] = _variant_t(5L); //how many requests to keep in a single pipe at once.
  66. g_defaults["max_message_length"] = _variant_t(pow(2, 23)); //maximum length prefix encoding you'll accept over the wire - larger values get the connection dropped.
  67. g_defaults["ip"] = _variant_t(""); //ip to report you have to the tracker.
  68. g_defaults["minport"] = _variant_t(6881L); //minimum port to listen on, counts up if unavailable
  69. g_defaults["maxport"] = _variant_t(6999L); //maximum port to listen on
  70. g_defaults["responsefile"] = _variant_t(""); //file the server response was stored in, alternative to url
  71. g_defaults["url"] = _variant_t(""); //alternative to responsefile
  72. g_defaults["saveas"] = _variant_t(""); //local file name to save the file as, null indicates query user
  73. g_defaults["timeout"] = _variant_t(300L); //time to wait between closing sockets which nothing has been received on
  74. g_defaults["timeout_check_interval"] = _variant_t(60L); //time to wait between checking if any connections have timed out
  75. g_defaults["max_slice_length"] = _variant_t(pow(2, 17)); //maximum length slice to send to peers, larger requests are ignored
  76. g_defaults["max_rate_period"] = _variant_t(3L); //maximum amount of time to guess the current rate estimate represents
  77. g_defaults["bind"] = _variant_t(""); //ip to bind to locally
  78. g_defaults["upload_rate_fudge"] = _variant_t(1L); //time equivalent of writing to kernel-level TCP buffer, for rate adjustment
  79. g_defaults["display_interval"] = _variant_t(5L); //time between updates of displayed information
  80. g_defaults["rerequest_interval"] = _variant_t(5*60L); //time to wait between requesting more peers
  81. g_defaults["min_peers"] = _variant_t(100L); //minimum number of peers to not do rerequesting
  82. g_defaults["http_timeout"] = _variant_t(60L); //number of seconds to wait before assuming that an http connection has timed out
  83. g_defaults["max_initiate"] = _variant_t(60L); //number of peers at which to stop initiating new connections
  84. g_defaults["check_hashes"] = _variant_t(1L); //whether to check hashes on disk
  85. g_defaults["max_upload_rate"] = _variant_t(0L); //maximum kB/s to upload at, 0 means no limit
  86. g_defaults["alloc_pause"] = _variant_t(3L); //seconds to wait before displaying allocation feedback
  87. g_defaults["snub_time"] = _variant_t(60L); //seconds to wait for data to come in over a connection before assuming it's semi-permanently choked
  88. g_defaults["spew"] = _variant_t(0L); //whether to display diagnostic info to stdout
  89. g_defaults["AllocSpeed"] = _variant_t(2L); //whether to display diagnostic info to stdout
  90. g_defaults["AllocType"] = _variant_t(0L); //whether to display diagnostic info to stdout
  91. g_defaults["FileOpenMax"] = _variant_t(0L); //whether to display diagnostic info to stdout
  92. g_defaults["SuperSeed"] = _variant_t(0L); //whether to display diagnostic info to stdout
  93. m_lUploadPeerMax = 4L;
  94. m_lUploadSpeedMax = 0;
  95. m_lConnectErrorMax = 200;
  96. m_lConnectIntval = 10;
  97. m_bLockFile = true;
  98. m_bLockFileWhileReading = false;
  99. m_bDoubleCheck = false;
  100. m_bTripleCheck = false;
  101. }
  102. void CDownload::SetParameter(CSetupRegister* pSetupRegister)
  103. {
  104. assert(pSetupRegister);
  105. assert(pSetupRegister->m_lAllocSpeed > 0 && pSetupRegister->m_lAllocSpeed <= 10);
  106. assert(pSetupRegister->m_eAllocType >= CStorageWrapperEx::eAllocNormal && 
  107. pSetupRegister->m_eAllocType <= CStorageWrapperEx::eAllocBackGound);
  108. assert(pSetupRegister->m_lFileOpenMax > 0 && pSetupRegister->m_lFileOpenMax < 250);
  109. g_defaults["minport"] = pSetupRegister->m_lPortMin;
  110. g_defaults["maxport"] = pSetupRegister->m_lPortMax;
  111. g_defaults["max_initiate"] = pSetupRegister->m_lPeersMax;
  112. g_defaults["min_peers"] = pSetupRegister->m_lPeersMin;
  113. g_defaults["display_interval"] = (long)(pSetupRegister->m_lDisplayItval);
  114. g_defaults["AllocSpeed"] = pSetupRegister->m_lAllocSpeed;
  115. g_defaults["AllocType"] = (long)pSetupRegister->m_eAllocType;
  116. g_defaults["FileOpenMax"] = pSetupRegister->m_lFileOpenMax;
  117. g_defaults["SuperSeed"] = pSetupRegister->m_bSuperSeed;
  118. m_lConnectErrorMax = pSetupRegister->m_lConnectErrorMax;
  119. m_lConnectIntval = pSetupRegister->m_lConnectIntval;
  120. if (pSetupRegister->m_lSendServerIP != INADDR_NONE )
  121. {
  122. in_addr inaddress;
  123. inaddress.S_un.S_addr = pSetupRegister->m_lSendServerIP;
  124. g_defaults["ip"] = inet_ntoa(inaddress);
  125. }
  126. switch (pSetupRegister->m_eFileLock)
  127. {
  128. case CSetupRegister::eFileUnlock:
  129. {
  130. m_bLockFile = false;
  131. m_bLockFileWhileReading = false;
  132. }
  133. break;
  134. case CSetupRegister::eFileWriteLock:
  135. {
  136. m_bLockFile = true;
  137. m_bLockFileWhileReading = false;
  138. }
  139. break;
  140. case CSetupRegister::eFileLock:
  141. {
  142. m_bLockFile = true;
  143. m_bLockFileWhileReading = true;
  144. }
  145. break;
  146. }
  147. switch (pSetupRegister->m_eExtraCheck)
  148. {
  149. case CSetupRegister::eNoExtraCheck:
  150. {
  151. m_bDoubleCheck = false;
  152. m_bTripleCheck = false;
  153. }
  154. break;
  155. case CSetupRegister::eDoubleCheck:
  156. {
  157. m_bDoubleCheck = true;
  158. m_bTripleCheck = false;
  159. }
  160. break;
  161. case CSetupRegister::eTripleCheck:
  162. {
  163. m_bDoubleCheck = true;
  164. m_bTripleCheck = true;
  165. }
  166. break;
  167. }
  168. // m_bCompleteKeepSeed = pSetupRegister->m_bCompleteKeepSeed;
  169. /*
  170. if(pSetupRegister->m_lDownSpeed < CSpeedParameters::eSpeedModeAll && pSetupRegister->m_lDownSpeed >=0)
  171. {
  172. g_defaults["max_uploads"] = _variant_t(CSpeedParameters::m_lArrPeerVal[pSetupRegister->m_lDownSpeed]);
  173. g_defaults["max_upload_rate"] = _variant_t(CSpeedParameters::m_lArrSpeedVal[pSetupRegister->m_lDownSpeed]);
  174. }
  175. else
  176. assert(false);
  177. //*/
  178. }
  179. void CDownload::CloseDownload()
  180. {
  181. if (IsEventSet(m_hThreadDone))
  182. {
  183. assert(false);
  184. }
  185. m_bClosing = true;
  186. if (IsPause()) Pause(false);
  187. SetEvent(m_hevDone);
  188. return;
  189. }
  190. void CDownload::Close()
  191. {
  192. if (!IsEventSet(m_hThreadDone))
  193. {
  194. if (IsPause())
  195. Pause(false);
  196. SetEvent(m_hevDone);
  197. DWORD dwRet = WaitForSingleObject(m_hThreadDone, INFINITE);
  198. switch (dwRet)
  199. {
  200. case WAIT_OBJECT_0:
  201. break;
  202. case WAIT_TIMEOUT:
  203. break;
  204. }
  205. }
  206. }
  207. bool CDownload::CanSetRunParameters()
  208. {
  209. return IsEventSet(m_hThreadSafe);
  210. }
  211. void CDownload::SetUnNeededFilesInxs(const vector<CSize>& vUnNeededFileInxs)
  212. {
  213. bool bToPause = !IsPause();
  214. if (bToPause) Pause(true);
  215. _SetUnNeededFilesInxs(vUnNeededFileInxs);
  216. if (bToPause) Pause(false);
  217. }
  218. void CDownload::_SetUnNeededFilesInxs(const vector<CSize>& vUnNeededFileInxs)
  219. {
  220. if (!IsDownloading() || !CanSetRunParameters())
  221. {
  222. assert(false);
  223. return;
  224. }
  225. if (!IsEventSet(m_hThreadSafe))
  226. {
  227. Pause(false);
  228. return;
  229. }
  230. if (!m_pStorageWrapper)
  231. {
  232. assert(false);
  233. return;
  234. }
  235. m_pStorageWrapper->SetUnNeededFilesInxs(vUnNeededFileInxs);
  236. }
  237. void CDownload::SetRunParameters(long lMaxUploadSpeed, long lMaxUploads, 
  238.  long lCompleteKeepSeedHour, long lConnectErrorMax, 
  239.  long lConnectIntval,
  240.  long minpeers, long maxpeers)
  241. {
  242. bool bToPause = !IsPause();
  243. if (bToPause) Pause(true);
  244. ASSERT(maxpeers > minpeers);
  245. _SetRunParameters(lMaxUploadSpeed, lMaxUploads, lCompleteKeepSeedHour, lConnectErrorMax, lConnectIntval, minpeers, maxpeers);
  246. if (bToPause) Pause(false);
  247. }
  248. void CDownload::_SetRunParameters(long lMaxUploadSpeed, long lMaxUploads,
  249.   long lCompleteKeepSeedHour, long lConnectErrorMax, 
  250.   long lConnectIntval,
  251.   long minpeers, long maxpeers)
  252. {
  253. assert(lMaxUploads > 0 && lMaxUploadSpeed >= 0);
  254. if (!IsDownloading() || !CanSetRunParameters())
  255. {
  256. assert(false);
  257. return;
  258. }
  259. if (!IsEventSet(m_hThreadSafe))
  260. {
  261. Pause(false);
  262. return;
  263. }
  264. if (m_pChoker && m_pconncetorget && m_pRequester && m_pEncrypter)
  265. {
  266. m_pChoker->SetMaxUploads(lMaxUploads);
  267. m_pconncetorget->SetMaxUploadRate(lMaxUploadSpeed * 1024);
  268. m_DownloaderFeedback.SetCompleteKeepSeedHour(lCompleteKeepSeedHour);
  269. m_pRequester->SetConnectErrorMax(lConnectErrorMax, lConnectIntval, minpeers, maxpeers);
  270. m_pEncrypter->SetMaxPeers(maxpeers);
  271. }
  272. else
  273. {
  274. assert(false);
  275. }
  276. }
  277. void CDownload::Pause(bool bPause)
  278. {
  279. if (bPause == IsPause())
  280. {
  281. assert(false);
  282. return;
  283. }
  284. if (bPause)
  285. {
  286. ResetEvent(m_hevUnPause);
  287. }
  288. else
  289. {
  290. SetEvent(m_hevUnPause);
  291. }
  292. }
  293. bool CDownload::IsPause()
  294. {
  295. return !IsEventSet(m_hevUnPause);
  296. }
  297. bool CDownload::IsDownloading()
  298. {
  299. return !IsEventSet(m_hThreadDone);
  300. }
  301. bool CDownload::IsBad()
  302. {
  303. return m_DownloaderFeedback.IsBad();
  304. }
  305. void CDownload::PausePeer(CAddrPort addrPort, bool bPause)
  306. {
  307. bool bToPause = !IsPause();
  308. if (bToPause) Pause(true);
  309. _PausePeer(addrPort, bPause);
  310. if (bToPause) Pause(false);
  311. }
  312. void CDownload::_PausePeer(CAddrPort addrPort, bool bPause)
  313. {
  314. if (!IsDownloading() || !m_pconncetorget || !CanSetRunParameters())
  315. {
  316. assert(false);
  317. return;
  318. }
  319. m_pconncetorget->PausePeer(addrPort, bPause);
  320. }
  321. void CDownload::ClosePeer(CAddrPort addrPort)
  322. {
  323. bool bToPause = !IsPause();
  324. if (bToPause) Pause(true);
  325. _ClosePeer(addrPort);
  326. if (bToPause) Pause(false);
  327. }
  328. void CDownload::_ClosePeer(CAddrPort addrPort)
  329. {
  330. if (!IsDownloading() || !m_pconncetorget || !CanSetRunParameters())
  331. {
  332. assert(false);
  333. return;
  334. }
  335. m_pconncetorget->ClosePeer(addrPort);
  336. }
  337. void CDownload::PartCompleted()
  338. {
  339. // SetEvent(m_hCompleted);
  340. m_pStorage->SetReadOnly();
  341. }
  342. void CDownload::Completed()
  343. {
  344. SetEvent(m_hCompleted);
  345. m_pStorage->SetReadOnly();
  346. if (m_pRequester)
  347. m_pRequester->AnnounceEx(REQ_COMPLETED);
  348. // todo:
  349. // send http request stoped.
  350. }
  351. void CDownload::data_flunked(long lAmount)
  352. {
  353. if (!m_pratemeasure)
  354. {
  355. ASSERT(FALSE);
  356. return;
  357. }
  358. m_pratemeasure->data_rejected(lAmount);
  359. TRACE("rn**********data_flunked****************rn");
  360. // todo:
  361. // ratemeasure.data_reject();
  362. }
  363. string CDownload::GetBadMsg()
  364. {
  365. return m_DownloaderFeedback.GetBadMsg();
  366. }
  367. /******************************************************************************
  368. parameter:
  369. lUploadSpeedMax unit is k.
  370. ******************************************************************************/
  371. bool CDownload::DownloadEx(CSetupRegister* pSetupRegister, 
  372. string strTorrentFileName, string strSaveFileName, bool bCheckHash, 
  373. HTREEITEM curItem, HWND hFeedbackwnd, long lParam, const CFileDBItem* const pFileDBItem)
  374. {
  375. if (strTorrentFileName.empty() || strSaveFileName.empty())
  376. {
  377. assert(false);
  378. return false;
  379. }
  380. assert(curItem && hFeedbackwnd && pSetupRegister);
  381. /////////////////////////////////////////////////////////////
  382. // pass parameter.
  383. SetParameter(pSetupRegister);
  384. m_vUnNeededFileInxs = pFileDBItem->m_vUnneededFileInx;
  385. m_lUploadPeerMax = pFileDBItem->m_lUploadPeerMax;
  386. m_lUploadSpeedMax = pFileDBItem->m_lUploadSpeedMax * 1024;
  387. m_lConnectErrorMax = pFileDBItem->m_lConnectErrorMax;
  388. m_lConnectIntval = pFileDBItem->m_lConnectIntval;
  389. g_defaults["max_initiate"] = pFileDBItem->m_lPeersMax;
  390. g_defaults["min_peers"] = pFileDBItem->m_lPeersMin;
  391. //
  392. // CDownloaderFeedback setdownload
  393. //
  394. m_DownloaderFeedback.SetDownload(this, curItem, hFeedbackwnd, pFileDBItem->m_lCompleteKeepSeedHour, lParam);
  395. /////////////////////////////////////////////////////////////
  396. // CFileTorrent
  397. m_bCheckHash = bCheckHash;
  398. m_strSaveFileName = strSaveFileName;
  399. m_strTorrentFileName = strTorrentFileName;
  400. try
  401. {
  402. if (!m_fileTorrernt.OpenFile(m_strTorrentFileName, m_strSaveFileName))
  403. {
  404. m_DownloaderFeedback.SetBadMsg(m_fileTorrernt.GetBadMsg(), false);
  405. return false;
  406. }
  407. if (!m_fileTorrernt.CreateDir(m_strSaveFileName))
  408. {
  409. assert(false);
  410. return false;
  411. }
  412. }
  413. catch (string e)
  414. {
  415. m_DownloaderFeedback.SetBadMsg(e, false);
  416. return false;
  417. }
  418. assert(IsEventSet(m_hThreadDone));
  419. ResetEvent(m_hThreadDone);
  420. ResetEvent(m_hCompleted);
  421. ResetEvent(m_hevDone);
  422. DWORD dwThreadId = 0;
  423. ::CreateThread(0, 0, DownloadProc, this, 0, &dwThreadId);
  424. TRACE("rndownload thread = (%x)rn", dwThreadId);
  425. return true;
  426. }
  427. ///////////////////////////////////////////////////////////
  428. // download thread
  429. ///////////////////////////////////////////////////////////
  430. DWORD WINAPI CDownload::DownloadProc(void *pParam)
  431. {
  432. CDownload* pdownload = (CDownload* )pParam;
  433. pdownload->DownloadProcEx();
  434. return 0;
  435. }
  436. void CDownload::DownloadProcEx()
  437. {
  438. // init socket.
  439. WORD wVersionRequested;
  440. WSADATA wsaData;
  441. wVersionRequested = MAKEWORD( 2, 2 ); 
  442. int err = WSAStartup( wVersionRequested, &wsaData );
  443. if ( err != 0 ) 
  444. return;
  445. // _CrtMemState s1, s2, s3;
  446. // _CrtMemCheckpoint( &s1 );
  447. Download();
  448. /*
  449. _CrtMemCheckpoint( &s2 );
  450. if ( _CrtMemDifference( &s3, &s1, &s2) )
  451. {
  452. _CrtMemDumpStatistics( &s3 );
  453. TRACE("rnendrn");
  454. }
  455. //*/
  456. WSACleanup();
  457. // if (!IsEventSet(m_hevDone))
  458. m_DownloaderFeedback.QuitDownload();
  459. SetEvent(m_hThreadDone);
  460. }
  461. void CDownload::Download()
  462. {
  463. try
  464. {
  465. //
  466. // CFileTorrent 
  467. //
  468. CVal* pInfo = m_fileTorrernt.GetInfo();
  469. CVal* pResponse = m_fileTorrernt.GetResponse();
  470. if (!pResponse) 
  471. {
  472. assert(false);
  473. return;
  474. }
  475. vector<CFileInfo>& vFiles = m_fileTorrernt.GetFileInfo();
  476. memstream& memMyid = m_fileTorrernt.GetMyId();
  477. memstream& memInfohash = m_fileTorrernt.GetInfohash();
  478. vector<char*>& vPieces = m_fileTorrernt.GetPieces();
  479. long lNumPieces = vPieces.size();
  480. //
  481. // CDownloaderFeedback setdownload
  482. //
  483. // m_DownloaderFeedback.SetDownload(this);
  484. CDownloader download;
  485. //
  486. // middle layer
  487. //
  488. // CChoker choker(g_defaults["max_uploads"], m_hCompleted);
  489. CChoker choker(m_lUploadPeerMax, m_hCompleted);
  490. m_pChoker = &choker;
  491. CConnector m_connector(m_lUploadSpeedMax);
  492. m_pconncetorget = &m_connector;
  493. CRerequester requester(m_lConnectErrorMax, m_lConnectIntval, g_defaults["min_peers"], g_defaults["max_initiate"]);
  494. assert(!m_pRequester);
  495. m_pRequester = &requester;
  496. CEncrypter encrypter(g_defaults["max_initiate"]);
  497. m_pEncrypter = &encrypter;
  498. //
  499. // CStorageWrapper
  500. //
  501. CStorage storage;
  502. m_pStorage = &storage;
  503. if (!storage.Create(&m_DownloaderFeedback, vFiles, m_hevDone, g_defaults["FileOpenMax"], m_bLockFile, m_bLockFileWhileReading))
  504. return;
  505. CStorageWrapper storageWrapper(m_vUnNeededFileInxs);
  506. m_pStorageWrapper = &storageWrapper;
  507. // Make sure user can manipulate run parameter.
  508. SetEvent(m_hThreadSafe);
  509. storageWrapper.Create(&m_DownloaderFeedback, m_hevDone, m_hevUnPause, 
  510. &storage, &download, vPieces, m_bCheckHash,  (long)g_defaults["download_slice_size"], (*pInfo)["piece length"]->lVal, 
  511. (CStorageWrapperEx::eAllocType)((long)g_defaults["AllocType"]), 
  512. g_defaults["AllocSpeed"], m_bDoubleCheck, m_bTripleCheck);
  513. // notify the window check completed.
  514. if (!IsEventSet(m_hevDone))
  515. m_DownloaderFeedback.StorageCheckComplete();
  516. CPiecePicker piecepicker(lNumPieces);
  517. CMeasure upmeasure(g_defaults["max_rate_period"], g_defaults["upload_rate_fudge"]);
  518. CMeasure downmeasure(g_defaults["max_rate_period"]);
  519. CRateMeasure ratemeasure(storageWrapper.get_amount_left(), &storageWrapper);
  520. m_pratemeasure = &ratemeasure;
  521. download.Create(&m_DownloaderFeedback, &storageWrapper, &piecepicker, g_defaults["request_backlog"], 
  522. g_defaults["max_rate_period"], &downmeasure, lNumPieces, 
  523. g_defaults["snub_time"], &ratemeasure);
  524. m_pdownloader = &download;
  525. CUploader uploader(&m_DownloaderFeedback, &storageWrapper, &choker, g_defaults["max_slice_length"], 
  526. g_defaults["max_rate_period"], g_defaults["upload_rate_fudge"]);
  527. // CConnector m_connector(&download, &uploader, &choker,
  528. //  lNumPieces, &storageWrapper, g_defaults["max_upload_rate"], &upmeasure);
  529. m_connector.Create(&download, &uploader, &choker,
  530.   lNumPieces, &storageWrapper, &upmeasure);
  531. // m_connector.SetMaxUploadRate(5000);
  532. encrypter.Create(&m_DownloaderFeedback, &m_connector, 
  533. memMyid, memInfohash, g_defaults["max_message_length"], g_defaults["keepalive_interval"]);
  534. // encrypter.start_connection("", 6881, memInfohash);
  535.  // return;
  536. //
  537. // create CDownloaderFeedback
  538. //
  539. m_DownloaderFeedback.Create(&m_connector, g_defaults["display_interval"]);
  540. // throw string("test error handle");
  541. //
  542. // create raw server
  543. //
  544. CRawServer rawserver(m_hevDone, m_hevUnPause, &encrypter, &choker, &m_connector, &m_DownloaderFeedback, m_pStorageWrapper);
  545. long lport = rawserver.Bind(g_defaults["minport"], g_defaults["maxport"]);
  546. if (!lport)
  547. {
  548. m_DownloaderFeedback.errorFunc("Couldn't listen - ");
  549. return;
  550. }
  551. m_DownloaderFeedback.PutRunParameter(lport);
  552. //
  553. // CRerequester : Get infomation from track.
  554. //
  555. string strIp = (char*)((_bstr_t)g_defaults["ip"]);
  556. requester.Create(&m_DownloaderFeedback, &storageWrapper, &upmeasure
  557. ,&downmeasure, &m_connector, &encrypter,
  558. (*pResponse)["announce"]->pstrVal, lport, strIp, memMyid, memInfohash, 
  559. g_defaults["rerequest_interval"],
  560. g_defaults["http_timeout"], m_hevDone);
  561. //
  562. // listen loop
  563. //
  564. rawserver.listen_forever(&requester);
  565. //
  566. // close.
  567. //
  568. storage.Close();
  569. requester.Close();
  570. // show end message.
  571. /*
  572. if (IsEventSet(m_hevDone))
  573. m_DownloaderFeedback.ShowSystemMessage("用户取消了该下载/上传", CSystemMsg::eCmd);
  574. else
  575. m_DownloaderFeedback.SetBadMsg("unknown reason terminate download");
  576. //*/
  577. ResetEvent(m_hThreadSafe);
  578. WaitForSingleObject(m_hevUnPause, INFINITE);
  579. }
  580. catch (string &e)
  581. {
  582. m_DownloaderFeedback.SetBadMsg(e);
  583. ResetEvent(m_hThreadSafe);
  584. WaitForSingleObject(m_hevUnPause, INFINITE);
  585. }
  586. }
  587. ///////////////////////////////////////////////////////////
  588. // download display
  589. ///////////////////////////////////////////////////////////
  590. void CDownload::GetFractions(vector<long>& vFractions)
  591. {
  592. m_DownloaderFeedback.GetFractions(vFractions);
  593. }
  594. void CDownload::GetRunParameter(long& lPort, long &lPeerMin, long &lPeerMax, 
  595. long &lDisplayItval, long &lAllocType, long&lFileOpenMax)
  596. {
  597. m_DownloaderFeedback.GetRunParameter(lPort);
  598. lPeerMin = g_defaults["min_peers"];
  599. lPeerMax = g_defaults["max_initiate"];
  600. lDisplayItval = g_defaults["display_interval"];
  601. lAllocType = g_defaults["AllocType"];
  602. lFileOpenMax = g_defaults["FileOpenMax"];
  603. }
  604. CDownloaderFeedback& CDownload::GetFeedback()
  605. {
  606. return m_DownloaderFeedback;
  607. }
  608. void CDownload::GetSystemMessage(vector<CSystemMsg>& vMsg)
  609. {
  610. m_DownloaderFeedback.GetSystemMessage(vMsg);
  611. }
  612. string CDownload::GetSocketMessageAll()
  613. {
  614. if (!IsDownloading()) 
  615. {
  616. assert(false);
  617. return "not in loop";
  618. }
  619. return m_DownloaderFeedback.GetSocketMessageAll();
  620. }
  621. string CDownload::GetSocketMessage(long lAddr, short sPort)
  622. {
  623. assert(IsDownloading());
  624. return m_DownloaderFeedback.GetSocketMessage(lAddr, sPort);
  625. }
  626. vector<CConncetionData>& CDownload::GetConnections()
  627. {
  628. assert(IsDownloading());
  629. return m_DownloaderFeedback.GetData();
  630. }
  631. CStatics& CDownload::GetStatics()
  632. {
  633. assert(IsDownloading());
  634. return m_DownloaderFeedback.GetStatics();
  635. }
  636. string CDownload::getmessage()
  637. {
  638. if (!IsDownloading())
  639. {
  640. assert(false);
  641. return "not in loop";
  642. }
  643. vector<CConncetionData>& vConnectionDatas = m_DownloaderFeedback.GetData();
  644. string strRet;
  645. for (int i=0; i<vConnectionDatas.size(); i++)
  646. {
  647. CConncetionData& connectionData = vConnectionDatas[i];
  648. {
  649. in_addr inaddress;
  650. inaddress.S_un.S_addr = connectionData.m_lAddr;
  651. char szText[1024] = {0};
  652. sprintf(szText, "peer - ip:%s:%d - Local:%d - uprate:%d - downrate:%d - downcount:%d - upcount:%d - havePercent:%d",
  653. inet_ntoa(inaddress),
  654. ntohs(connectionData.m_sPort),
  655. connectionData.m_bLocallyInitiated,
  656. connectionData.m_lUpRate,
  657. connectionData.m_lDownRate,
  658. connectionData.m_lDownCount,
  659. connectionData.m_lUpCount,
  660. connectionData.m_fPeerHavePercent
  661. );
  662. strRet += szText;
  663. strRet += "rn";
  664. }
  665. }
  666. return strRet;
  667. /*
  668. char szText[100] = {0};
  669. string  strRet;
  670. long lrate = 0;
  671. lrate = m_pdownloader->m_pDownMeasure->get_rate();
  672. sprintf(szText, "global download rate : (%d)", lrate);
  673. strRet += szText;
  674. strRet += "rn";
  675. lrate = m_pconncetorget->how_many_connections();
  676. sprintf(szText, "connections size : (%d)", lrate);
  677. strRet += szText;
  678. strRet += "rn";
  679. for (int i=0; i<m_pconncetorget->m_connections.size();i++)
  680. {
  681. string strIp = m_pconncetorget->m_connections[i]->GetIP();
  682. strRet += "ip : (" + strIp + ")";
  683. lrate = m_pconncetorget->m_connections[i]->m_pDownload->get_rate();
  684. sprintf(szText, "peer -- download rate : (%d)", lrate);
  685. strRet += szText;
  686. lrate = m_pconncetorget->m_connections[i]->m_pUpload->get_rate();
  687. sprintf(szText, " -- upload rate : (%d)", lrate);
  688. strRet += szText;
  689. long lHaveCount = m_pconncetorget->m_connections[i]->m_pDownload->GetHaveCountPercent();
  690. sprintf(szText, " -- have count: (%d)", lHaveCount);
  691. strRet += szText;
  692. strRet += "rn";
  693. }
  694. lrate = m_pdownloader->m_pRateMeasure->get_size_left();
  695. sprintf(szText, "size left: (%d)", lrate);
  696. strRet += szText;
  697. strRet += "rn";
  698. lrate = m_pdownloader->m_pRateMeasure->get_time_left();
  699. tm* tt = localtime(&lrate);
  700. if (tt)
  701. sprintf(szText, "time left: (%d:%d:%d:%d)", tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec);
  702. else
  703. sprintf(szText, "time left: no");
  704. strRet += szText;
  705. strRet += "rn";
  706. //*/
  707. return strRet;
  708. }
  709. /////////////////////////////////////////////////////////////////////////////////////////////
  710. //
  711. // for test
  712. //
  713. /////////////////////////////////////////////////////////////////////////////////////////////
  714. void CDownload::test()
  715. {
  716. /*
  717. CVal* pRet = 0;
  718. CBdecode dec;
  719. char buf[] = "i1000e";
  720. pRet = dec.bdecode(buf, sizeof(buf)/sizeof(char));
  721. if (pRet)
  722. delete pRet;
  723. char buf1[] = "5:hello";
  724. pRet = dec.bdecode(buf1, sizeof(buf1)/sizeof(char));
  725. if (pRet)
  726. delete pRet;
  727. //*/
  728. // ShowMessage((*pRet).data());
  729. // CVal::test();
  730. // CStorage::test();
  731. /*
  732. long ltime = 0;
  733. time(&ltime);
  734. srand(ltime);
  735. PiecePickerTest();
  736. //*/
  737. // RateMeasureTest();
  738. // SingleDownloadTest();
  739. /*
  740. char pbuf[262144] = {0};
  741. for (int i=0; i<262144; i++)
  742. {
  743. pbuf[i] = i;
  744. }
  745. for (i=0; i<3000; i++)
  746. {
  747. SHA1 sha;
  748. unsigned int shaRes[5] = {0};
  749. sha.Input(pbuf, 262144);
  750. sha.Result(shaRes);
  751. TRACE("%d, ", i/30);
  752. if (!(i %20))
  753. TRACE("rn");
  754. }
  755. //*/
  756. }