Skip to content

Commit 2c75842

Browse files
committed
Example:Download Example Support P2P Download
1 parent f72a47f commit 2c75842

File tree

2 files changed

+145
-3
lines changed

2 files changed

+145
-3
lines changed

XEngine_APPClient/APPClient_Download/APPClient_Download.cpp

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,149 @@
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

18148
int 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;

XEngine_APPClient/APPClient_Download/APPClient_Download.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
<ClCompile>
8989
<WarningLevel>Level3</WarningLevel>
9090
<SDLCheck>true</SDLCheck>
91-
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
91+
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9292
<ConformanceMode>true</ConformanceMode>
9393
</ClCompile>
9494
<Link>

0 commit comments

Comments
 (0)