Skip to content

Commit f2e58e1

Browse files
authored
Merge pull request #10 from libxengine/develop
V2.2 Merge
2 parents fdaf7e4 + c653bc0 commit f2e58e1

36 files changed

+600
-246
lines changed

README.en.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
[中文](README.md) || [English](README.en.md)
12
# XEngine_Storage
3+
This repository has a development and master branch. If you want to use it, please use the master branch
24

35
## Introduction
46
c c++ 存储服务 c c++ 文件存储服务
@@ -10,7 +12,6 @@ best storage service for http,batter than nginx and more convenient to manage. O
1012

1113
## Software feature
1214
The purpose of development and implementation based on libXEngine is a cross-platform network storage service
13-
This repository has a development and master branch. If you want to use it, please use the master branch
1415

1516
feature list:
1617
1. support file http upload and download(use put and get method)
@@ -25,9 +26,10 @@ feature list:
2526
10. support p2p
2627
11. bt(planning)
2728
12. data distributed
28-
13. support second pass
29+
13. support second pass and Resumable
2930
14. support nginx upload module proxy_pass
3031
15. support upload and download Redirect
32+
16. dynamic rate of the download
3133

3234
## install
3335

@@ -85,6 +87,10 @@ The Second pass is not realized by the server, it is by the client
8587
upload file second pass is first check the HASH file is on the server, if has file on the server, it will directly prompt the upload is successful.
8688
The realization of downloading second transmission is to first query the local file save path through HASH, and download it directly if it exists.
8789

90+
## 关于P2P
91+
P2P distributed download has been supported, but currently only in the lan,cross-network segment is not supported for the time being, you need to wait for the development to be completed
92+
P2P distributed download is the same as the hyper-threaded download of other download tools. The principle is to use the HTTP RANGE field. You can implement this function through libraries such as libcurl.
93+
8894
## directory struct
8995
- XEngine_Docment docment directory
9096
- XEngine_Release install directory
@@ -94,7 +100,6 @@ The realization of downloading second transmission is to first query the local f
94100

95101
## now task
96102
expand management interface
97-
P2P
98103

99104
## other problems
100105
You can refer to the document under the docment directory. It contains API protocol and service description.

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
[中文](README.md) || [English](README.en.md)
12
# XEngine_Storage
3+
本仓库有开发和主分支,如果要使用,请使用master分支下的代码
24

35
## 介绍
46
c c++ 存储服务 c c++ 文件存储服务
@@ -10,7 +12,6 @@ c c++ file storage service
1012

1113
## 软件特性
1214
基于libXEngine开发并实现的一套简洁高性能跨平台网络存储服务
13-
本仓库有开发和主分支,如果要使用,请使用master分支下的代码
1415
软件特性:
1516
1. 支持HTTP协议上传和下载(采用PUT和GET)
1617
2. 支持HTTP API接口事件通知与管理
@@ -24,9 +25,10 @@ c c++ file storage service
2425
10. 支持P2P
2526
11. BT(规划中)
2627
12. 数据分发
27-
13. 支持秒传
28+
13. 支持秒传和断点续传
2829
14. 支持NGINX UPLOAD MODULE上传代理
2930
15. 支持上传和下载重定向
31+
16. 下载动态速率
3032

3133
## 安装教程
3234

@@ -90,9 +92,12 @@ make FLAGS=CleanAll 清理编译
9092
上传秒传的实现是先通过HASH查询文件是否在服务器,如果存在就不上传直接提示客户端上传成功.
9193
下载秒传的实现是先通过HASH查询本地文件保存路径,如果存在就直接下载完成.
9294

95+
## 关于P2P
96+
P2P分布式下载已经支持,不过目前只能在局域网中,暂时不支持跨网段,需要等待开发完毕
97+
P2P分布式下载与其他下载工具的超线程下载一样,原理是使用HTTP RANGE字段实现.各位可以通过libcurl等库实现此功能.
98+
9399
## 当前任务
94100
扩展管理接口
95-
实现P2P
96101

97102
## 其他问题
98103
你可以参考docment目录下的文档.里面包含了API协议和服务说明.

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>

XEngine_Docment/.gitignore

Whitespace-only changes.

XEngine_Docment/Docment_en.docx

1.34 KB
Binary file not shown.

XEngine_Docment/Docment_zh.docx

1.66 KB
Binary file not shown.

XEngine_Release/XEngine_Config/XEngine_Config.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"tszIPAddr": "192.168.1.7",
2+
"tszIPAddr": "192.168.1.9",
33
"bDeamon": 0,
44
"nCenterPort": 5100,
55
"nStorageDLPort": 5101,
@@ -38,7 +38,7 @@
3838
"XStorage": {
3939
"nHashMode": 2,
4040
"bRename": 0,
41-
"tszFileDir": "./XEngine_File"
41+
"tszFileDir": "/home/ubuntu/桌面/XEngine_Storage/XEngine_Source/Debug/XEngine_File"
4242
},
4343
"XProxy": {
4444
"XProxyAuth": {
@@ -54,18 +54,21 @@
5454
}
5555
},
5656
"XLimit": {
57+
"nDLTry": 100,
58+
"nDLError": 10,
5759
"nMaxUPLoad": 0,
58-
"nMaxDNLoad": 1024000
60+
"nMaxDNLoad": 10240000
5961
},
6062
"XP2xp": {
61-
"nMode": 0,
63+
"nMode": 2,
6264
"nTime": 2,
6365
"nSDPort": 15000,
6466
"nRVPort": 15001,
6567
"tszQQWryFile": "./XEngine_SQL/qqwry.dat"
6668
},
6769
"XVer": {
6870
"StorageVersion": [
71+
"2.2.0.1001 Build20210820",
6972
"2.1.0.1001 Build20210805",
7073
"2.0.0.1001 Build20210723",
7174
"1.5.0.1001 Build20210716",
@@ -76,4 +79,4 @@
7679
"1.0.0.1001 Build20210501"
7780
]
7881
}
79-
}
82+
}

XEngine_Source/StorageModule_Config/Config_Define.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ typedef struct tag_XEngine_ServerConfig
8484
}st_XProxy;
8585
struct
8686
{
87+
int nDLTry;
88+
int nDLError;
8789
__int64x nMaxUPLoader;
8890
__int64x nMaxDNLoader;
8991
}st_XLimit;

XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,15 @@ BOOL CConfig_Json::Config_Json_File(LPCTSTR lpszConfigFile,XENGINE_SERVERCONFIG
155155
_tcscpy(pSt_ServerConfig->st_XProxy.st_XProxyPass.tszDLPass, st_JsonXProxyPass["tszDLPass"].asCString());
156156
_tcscpy(pSt_ServerConfig->st_XProxy.st_XProxyPass.tszUPPass, st_JsonXProxyPass["tszUPPass"].asCString());
157157

158-
if (st_JsonRoot["XLimit"].empty() || (2 != st_JsonRoot["XLimit"].size()))
158+
if (st_JsonRoot["XLimit"].empty() || (4 != st_JsonRoot["XLimit"].size()))
159159
{
160160
Config_IsErrorOccur = TRUE;
161161
Config_dwErrorCode = ERROR_XENGINE_BLOGIC_CONFIG_JSON_XSTORAGE;
162162
return FALSE;
163163
}
164164
Json::Value st_JsonXLimit = st_JsonRoot["XLimit"];
165+
pSt_ServerConfig->st_XLimit.nDLTry = st_JsonXLimit["nDLTry"].asUInt();
166+
pSt_ServerConfig->st_XLimit.nDLError = st_JsonXLimit["nDLError"].asUInt();
165167
pSt_ServerConfig->st_XLimit.nMaxDNLoader = st_JsonXLimit["nMaxDNLoad"].asInt64();
166168
pSt_ServerConfig->st_XLimit.nMaxUPLoader = st_JsonXLimit["nMaxUPLoad"].asInt64();
167169

0 commit comments

Comments
 (0)