1- #ifdef _WINDOWS
1+ // P2P 分布式(超线程下载示例代码),目前仅支持局域网,示例代码仅仅是演示如何实现,正式使用需要做调整
2+ // P2P Distributed(Hyper-Threading download sample code),only supports LAN,The example code is just to demonstrate how to implement it, and it needs to be adjusted for business
3+ // 你可以使用libcurl实现HTTP下载功能,主要是利用了Range字段实现分块下载
4+ // You can use libcurl to implement the HTTP download, mainly using the Range field to achieve block download
5+ #ifdef _WINDOWS
26#include < windows.h>
37#include < tchar.h>
48#else
59#endif
10+ #include < list>
611#include < json/json.h>
712#include < XEngine_Include/XEngine_CommHdr.h>
13+ #include < XEngine_Include/XEngine_Types.h>
14+ #include < XEngine_Include/XEngine_ProtocolHdr.h>
815#include < XEngine_Include/XEngine_BaseLib/BaseLib_Define.h>
916#include < XEngine_Include/XEngine_BaseLib/BaseLib_Error.h>
1017#include < XEngine_Include/XEngine_NetHelp/APIHelp_Define.h>
1118#include < XEngine_Include/XEngine_NetHelp/APIHelp_Error.h>
19+ #include < XEngine_Include/XEngine_DownLoad/DownLoad_Define.h>
20+ #include < XEngine_Include/XEngine_DownLoad/DownLoad_Error.h>
21+ #include < XEngine_Include/XEngine_SystemSdk/ProcFile_Define.h>
22+ #include < XEngine_Include/XEngine_SystemSdk/SystemApi_Define.h>
23+ #include < XEngine_Include/XEngine_SystemSdk/SystemApi_Error.h>
24+ using namespace std ;
1225
1326#pragma comment(lib,"x86/XEngine_BaseLib/XEngine_BaseLib")
1427#pragma comment(lib,"x86/XEngine_NetHelp/NetHelp_APIHelp")
28+ #pragma comment(lib,"x86/XEngine_DownLoad/XEngine_DownLoad")
29+ #pragma comment(lib,"x86/XEngine_SystemSdk/XEngine_SystemApi")
1530#pragma comment(lib,"Ws2_32")
1631
32+ typedef struct
33+ {
34+ XENGINE_PROTOCOLFILE st_ProtocolFile;
35+ CHAR tszIPAddr[64 ];
36+ }P2PFILE_INFO;
37+
38+ // 解析局域网中所有文件
39+ void P2PParse_List (LPCTSTR lpszMsgBuffer, int nMsgLen, list<P2PFILE_INFO>* pStl_ListFile)
40+ {
41+ Json::Value st_JsonRoot;
42+ Json::CharReaderBuilder st_JsonBuild;
43+ Json::CharReader* pSt_JsonReader (st_JsonBuild.newCharReader ());
44+
45+ JSONCPP_STRING st_JsonError;
46+ // 解析JSON
47+ if (!pSt_JsonReader->parse (lpszMsgBuffer, lpszMsgBuffer + nMsgLen, &st_JsonRoot, &st_JsonError))
48+ {
49+ return ;
50+ }
51+ delete pSt_JsonReader;
52+ pSt_JsonReader = NULL ;
53+
54+ int nCount = st_JsonRoot[" Count" ].asInt ();
55+ Json::Value st_JsonArray = st_JsonRoot[" List" ];
56+ for (int i = 0 ; i < nCount; i++)
57+ {
58+ P2PFILE_INFO st_P2PFile;
59+ memset (&st_P2PFile, ' \0 ' , sizeof (P2PFILE_INFO));
60+
61+ st_P2PFile.st_ProtocolFile .nFileSize = st_JsonArray[i][" nFileSize" ].asInt ();
62+ _tcscpy (st_P2PFile.st_ProtocolFile .tszFileHash , st_JsonArray[i][" tszFileHash" ].asCString ());
63+ _tcscpy (st_P2PFile.st_ProtocolFile .tszFileName , st_JsonArray[i][" tszFileName" ].asCString ());
64+ _tcscpy (st_P2PFile.st_ProtocolFile .tszFilePath , st_JsonArray[i][" tszFilePath" ].asCString ());
65+ _tcscpy (st_P2PFile.st_ProtocolFile .tszFileTime , st_JsonArray[i][" tszFileTime" ].asCString ());
66+ _tcscpy (st_P2PFile.st_ProtocolFile .tszFileUser , st_JsonArray[i][" tszFileUser" ].asCString ());
67+ _tcscpy (st_P2PFile.tszIPAddr , st_JsonArray[i][" tszTableName" ].asCString ());
68+
69+ pStl_ListFile->push_back (st_P2PFile);
70+ }
71+ }
72+ // 创建分布式文件下载器
73+ typedef struct
74+ {
75+ XNETHANDLE xhToken; // 下载句柄
76+ __int64x nPosStart;
77+ __int64x nPosEnd;
78+ }P2PFILE_PIECE;
79+ void P2PFile_Create (list<P2PFILE_INFO>* pStl_ListFile, LPCTSTR lpszFile)
80+ {
81+ P2PFILE_PIECE* pSt_P2PFile = new P2PFILE_PIECE[pStl_ListFile->size ()];
82+
83+ int nPos = 0 ;
84+ // 得到每个块大小
85+ int nPiece = pStl_ListFile->front ().st_ProtocolFile .nFileSize / pStl_ListFile->size ();
86+ // 这是一个简单的分布式块算法示例.怎么做分布式,可以根据自己需求做算法拆解
87+ list<P2PFILE_INFO>::const_iterator stl_ListIterator = pStl_ListFile->begin ();
88+ for (int i = 0 ; stl_ListIterator != pStl_ListFile->end (); stl_ListIterator++, i++)
89+ {
90+ TCHAR tszDLUrl[MAX_PATH];
91+ TCHAR tszRange[128 ];
92+
93+ memset (tszDLUrl, ' \0 ' , MAX_PATH);
94+ memset (tszRange, ' \0 ' , sizeof (tszRange));
95+
96+ _stprintf (tszDLUrl, _T (" %s/%s/%s" ), stl_ListIterator->tszIPAddr , stl_ListIterator->st_ProtocolFile .tszFilePath + 2 , stl_ListIterator->st_ProtocolFile .tszFileName );
97+ // 是否是最后一块
98+ if (pStl_ListFile->size () == (i + 1 ))
99+ {
100+ pSt_P2PFile[i].nPosStart = nPos;
101+ pSt_P2PFile[i].nPosEnd = 0 ;
102+ _stprintf (tszRange, _T (" %lld-" ), pSt_P2PFile[i].nPosStart );
103+ }
104+ else
105+ {
106+ pSt_P2PFile[i].nPosStart = nPos;
107+ pSt_P2PFile[i].nPosEnd = nPiece;
108+ nPos += nPiece;
109+ _stprintf (tszRange, _T (" %lld-%lld" ), pSt_P2PFile[i].nPosStart , pSt_P2PFile[i].nPosEnd );
110+ }
111+
112+ if (!DownLoad_Http_Create (&pSt_P2PFile[i].xhToken , tszDLUrl, lpszFile, tszRange, NULL , NULL , NULL ))
113+ {
114+ printf (" create download task is failed:%lX\n " , Download_GetLastError ());
115+ }
116+ }
117+ // 直到所有完成
118+ while (1 )
119+ {
120+ BOOL bComplete = TRUE ;
121+ for (unsigned int i = 0 ; i < pStl_ListFile->size (); i++)
122+ {
123+ NETDOWNLOAD_TASKINFO st_TaskInfo;
124+ memset (&st_TaskInfo, ' \0 ' , sizeof (NETDOWNLOAD_TASKINFO));
125+
126+ DownLoad_Http_Query (pSt_P2PFile[i].xhToken , &st_TaskInfo);
127+ if (ENUM_XENGINE_DOWNLOAD_STATUS_COMPLETE != st_TaskInfo.en_DownStatus )
128+ {
129+ bComplete = FALSE ;
130+ }
131+ printf (" DLToken:%lld DLTotal:%lf DLNow:%lf DLStatus:%d\n " , pSt_P2PFile[i].xhToken , st_TaskInfo.dlTotal , st_TaskInfo.dlNow , st_TaskInfo.en_DownStatus );
132+ }
133+ if (bComplete)
134+ {
135+ break ;
136+ }
137+ Sleep (500 );
138+ }
139+
140+ for (unsigned int i = 0 ; i < pStl_ListFile->size (); i++)
141+ {
142+ DownLoad_Http_Delete (pSt_P2PFile[i].xhToken );
143+ }
144+ delete[] pSt_P2PFile;
145+ pSt_P2PFile = NULL ;
146+ }
17147
18148int main ()
19149{
@@ -24,13 +154,25 @@ int main()
24154 int nBodyLen = 2048 ;
25155 TCHAR *ptszMsgBody = NULL ;
26156 // 请求分布式存储文件所有位置
27- LPCTSTR lpszUrl = _T (" http://192.168.1.7:5100/EC9B9B75A04F3B323EFD348F9B795539" );
157+ LPCTSTR lpszUrl = _T (" http://127.0.0.1:5100/7D54D6E40367F2763B8C8056EADC517F" );
158+ LPCTSTR lpszFile = _T (" D:\\ XEngine_Storage\\ XEngine_APPClient\\ Debug\\ qq.exe" );
159+
28160 if (!APIHelp_HttpRequest_Get (lpszUrl, &ptszMsgBody, &nBodyLen, &nHTTPCode))
29161 {
30162 return -1 ;
31163 }
32164 printf (" %s\n " , ptszMsgBody);
33165
166+ list<P2PFILE_INFO> stl_ListFile;
167+ P2PParse_List (ptszMsgBody, nBodyLen, &stl_ListFile);
168+
169+ // 创建稀疏文件(一个空白的文件)
170+ if (!SystemApi_File_CreateSparseFile (lpszFile, stl_ListFile.front ().st_ProtocolFile .nFileSize ))
171+ {
172+ return -1 ;
173+ }
174+ P2PFile_Create (&stl_ListFile, lpszFile);
175+
34176 BaseLib_OperatorMemory_FreeCStyle ((VOID**)&ptszMsgBody);
35177 WSACleanup ();
36178 return 0 ;
0 commit comments