Initial commit
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/../common",
|
||||
"${workspaceFolder}/../param",
|
||||
"${workspaceFolder}/../StoredProcedure"
|
||||
],
|
||||
"defines": ["_DEBUG","_SERVER"],
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "gnu++14",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "C/C++: g++ build and debug active file",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../deploy/DBService",
|
||||
"args": ["-debug", "s"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/../deploy",
|
||||
"environment": [
|
||||
{
|
||||
"name": "LD_LIBRARY_PATH",
|
||||
"value": "LD_LIBRARY_PATH:${workspaceFolder}/../deploy"
|
||||
}
|
||||
],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "C/C++: g++ build DBService",
|
||||
"miDebuggerPath": "/usr/bin/gdb",
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"C_Cpp.default.includePath": [
|
||||
"${workspaceFolder}/../common",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cppbuild",
|
||||
"label": "C/C++: g++ build DBService",
|
||||
"command": "/usr/bin/g++",
|
||||
"args": [
|
||||
"-fdiagnostics-color=always",
|
||||
"-g",
|
||||
"-D","_DEBUG",
|
||||
"-D","_SERVER",
|
||||
"${workspaceFolder}/*.cpp",
|
||||
"${workspaceFolder}/../common/thread.cpp",
|
||||
"${workspaceFolder}/../common/Socket.cpp",
|
||||
"${workspaceFolder}/../common/MessageDef.cpp",
|
||||
"-std=c++11",
|
||||
"-I","${workspaceFolder}/../common",
|
||||
"-I","${workspaceFolder}/../param",
|
||||
"-I","${workspaceFolder}/../StoredProcedure",
|
||||
"-L","${workspaceFolder}/../deploy",
|
||||
"-l","StoredProcedure",
|
||||
"-l","Params",
|
||||
"-Wl,--copy-dt-needed-entries",
|
||||
"-o","${workspaceFolder}/../deploy/DBService",
|
||||
"-pthread",
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"detail": "Task generated by Debugger."
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ServiceThread.h"
|
||||
#include "debug.h"
|
||||
|
||||
int g_eDebug = 0;
|
||||
int g_iChkStyle = 0;
|
||||
|
||||
extern int g_iSignal;
|
||||
extern CSema* g_pSemaService;
|
||||
CSema* g_pSemaStop = NULL;
|
||||
|
||||
void CmdDebugService()
|
||||
{
|
||||
CServiceThread* pServiceThread = new CServiceThread();
|
||||
pServiceThread->Resume();
|
||||
|
||||
g_pSemaStop = new CSema(NULL, 0);
|
||||
g_pSemaStop->ActP();
|
||||
|
||||
pServiceThread->Terminate();
|
||||
if( g_pSemaService ){
|
||||
if( g_pSemaService->ActP(15000) ){
|
||||
printf("service eixt innormally\n");
|
||||
}
|
||||
delete g_pSemaService;
|
||||
}
|
||||
|
||||
delete pServiceThread;
|
||||
delete g_pSemaStop;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if ( (argc > 1) &&((*argv[1] == '-') || (*argv[1] == '/')) ){
|
||||
if ( strcasecmp( "debug", argv[1]+1 ) == 0 ){
|
||||
g_eDebug = 4;
|
||||
|
||||
if( argc>2 ){
|
||||
if ( strcasecmp( "f", argv[2] ) == 0 ){
|
||||
g_eDebug = 1;
|
||||
}
|
||||
else if ( strcasecmp( "n", argv[2] ) == 0 ){
|
||||
g_eDebug = 2;
|
||||
}
|
||||
else if ( strcasecmp( "s", argv[2] ) == 0 ){
|
||||
g_eDebug = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( strcasecmp( "check", argv[1]+1 ) == 0 && argc>2 ){
|
||||
g_iChkStyle = atoi(argv[2]);
|
||||
|
||||
if( g_iChkStyle>0 ){
|
||||
g_eDebug = 3;
|
||||
}
|
||||
}
|
||||
|
||||
CmdDebugService();
|
||||
}
|
||||
|
||||
return g_iSignal;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include "typedef.h"
|
||||
#include "commonstruct.h"
|
||||
#include "ProCommon.h"
|
||||
#include "ServerInner.h"
|
||||
#include "Param.h"
|
||||
#include "StoredProcedure.h"
|
||||
#endif
|
||||
|
||||
#include "DBInterface.h"
|
||||
#include "debug.h"
|
||||
|
||||
typedef DLLAPI int (*DB_INITDATABASES)(char* strHost, char* strUser, char* strPwd);
|
||||
typedef DLLAPI int (*DB_RELEASE)();
|
||||
DB_INITDATABASES f_DB_InitDatabases = NULL;
|
||||
DB_RELEASE f_DB_Release = NULL;
|
||||
|
||||
PM_HANDLEPARAM f_PM_HandleParam = NULL;
|
||||
DB_GETCLIENTVERSION f_DB_GetClientVersion = NULL;
|
||||
DB_GETCLIENTTYPENUMBER f_DB_GetClientTypeNumber = NULL;
|
||||
DB_GETPATH f_DB_GetPath = NULL;
|
||||
DB_CLEANVIPLOG f_DB_CleanVipLog = NULL;
|
||||
DB_PHONECHECK f_DB_PhoneCheck = NULL;
|
||||
DB_REGISTER f_DB_Register = NULL;
|
||||
DB_LOGIN f_DB_Login = NULL;
|
||||
DB_LOGOFF f_DB_Logoff = NULL;
|
||||
DB_GETSTYLEUPDATENUMBER f_DB_GetStyleUpdateNumber = NULL;
|
||||
DB_GETCLIENTUPDATEFLAG f_DB_GetClientUpdateFlag = NULL;
|
||||
DB_VERIFY f_DB_Verify = NULL;
|
||||
DB_PURCHASE f_DB_Purchase = NULL;
|
||||
DB_INSERTSTYLE f_DB_InsertStyle = NULL;
|
||||
DB_GETSTYLEUPDATELIST f_DB_GetStyleUpdateList = NULL;
|
||||
DB_CHECKSTYLEINFO f_DB_CheckStyleInfo = NULL;
|
||||
DB_GETRECOMSTYLEIDS f_DB_GetRecomStyleIDs = NULL;
|
||||
DB_CHECKUSERAUTHORITY f_DB_CheckUserAuthority = NULL;
|
||||
DB_SETSTYLECHECK f_DB_SetStyleCheck = NULL;
|
||||
DB_GETCOMMONQNA f_DB_GetCommonQnA = NULL;
|
||||
DB_GETUSERQNA f_DB_GetUserQnA = NULL;
|
||||
DB_SUBMITQUESTION f_DB_SubmitQuestion = NULL;
|
||||
DB_GETNOTICE f_DB_GetNotice = NULL;
|
||||
DB_INSERTSONG f_DB_InsertSong = NULL;
|
||||
DB_GETSTYLEUPDATELISTNEW f_DB_GetStyleUpdateListNew = NULL;
|
||||
DB_GETSHAREUPDATELIST f_DB_GetShareUpdateList = NULL;
|
||||
DB_GETCHECKUPDATELIST f_DB_GetCheckUpdateList = NULL;
|
||||
DB_GETSTYLEINFONEW f_DB_GetStyleInfoNew = NULL;
|
||||
DB_UPDATESTYLE f_DB_UpdateStyle = NULL;
|
||||
DB_CHECKPAYMENT f_DB_CheckPayment = NULL;
|
||||
DB_CONFIRMPAYMENT f_DB_ConfirmPayment = NULL;
|
||||
DB_STYLESCORE f_DB_StyleScore = NULL;
|
||||
DB_INSERTSHARESTYLE f_DB_InsertShareStyle = NULL;
|
||||
DB_GETWEBURL f_DB_GetWebURL = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
HINSTANCE g_hDBDll = NULL,
|
||||
g_hPMDll = NULL;
|
||||
#endif
|
||||
bool LoadDB()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
g_hDBDll = LoadLibrary( DB_DLL );
|
||||
if( g_hDBDll==NULL ){
|
||||
DWORD dwRet = GetLastError();
|
||||
|
||||
DebugPrint( "载入数据库接口模块失败, 程序终止! errcode=%d", dwRet );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//获取数据库函数入口
|
||||
f_DB_InitDatabases = (DB_INITDATABASES)GetProcAddress( g_hDBDll, "DB_InitDatabases" );
|
||||
f_DB_Release = (DB_RELEASE)GetProcAddress( g_hDBDll, "DB_Release" );
|
||||
f_DB_GetPath = (DB_GETPATH)GetProcAddress( g_hDBDll, "DB_GetPath" );
|
||||
f_DB_CleanVipLog = (DB_CLEANVIPLOG)GetProcAddress( g_hDBDll, "DB_CleanVipLog" );
|
||||
f_DB_GetClientVersion = (DB_GETCLIENTVERSION)GetProcAddress( g_hDBDll, "DB_GetClientVersion" );
|
||||
f_DB_GetClientTypeNumber = (DB_GETCLIENTTYPENUMBER)GetProcAddress( g_hDBDll, "DB_GetClientTypeNumber" );
|
||||
f_DB_GetStyleUpdateNumber = (DB_GETSTYLEUPDATENUMBER)GetProcAddress( g_hDBDll, "DB_GetStyleUpdateNumber" );
|
||||
f_DB_GetClientUpdateFlag = (DB_GETCLIENTUPDATEFLAG)GetProcAddress( g_hDBDll, "DB_GetClientUpdateFlag" );
|
||||
f_DB_PhoneCheck = (DB_PHONECHECK)GetProcAddress( g_hDBDll, "DB_PhoneCheck" );
|
||||
f_DB_Register = (DB_REGISTER)GetProcAddress( g_hDBDll, "DB_Register" );
|
||||
f_DB_Login = (DB_LOGIN)GetProcAddress( g_hDBDll, "DB_Login" );
|
||||
f_DB_Logoff = (DB_LOGOFF)GetProcAddress( g_hDBDll, "DB_Logoff" );
|
||||
f_DB_Verify = (DB_VERIFY)GetProcAddress( g_hDBDll, "DB_Verify" );
|
||||
f_DB_Purchase = (DB_PURCHASE)GetProcAddress( g_hDBDll, "DB_Purchase" );
|
||||
f_DB_InsertStyle = (DB_INSERTSTYLE)GetProcAddress( g_hDBDll, "DB_InsertStyle" );
|
||||
f_DB_GetStyleUpdateList = (DB_GETSTYLEUPDATELIST)GetProcAddress( g_hDBDll, "DB_GetStyleUpdateList" );
|
||||
f_DB_CheckStyleInfo = (DB_CHECKSTYLEINFO)GetProcAddress( g_hDBDll, "DB_CheckStyleInfo" );
|
||||
f_DB_GetRecomStyleIDs = (DB_GETRECOMSTYLEIDS)GetProcAddress( g_hDBDll, "DB_GetRecomStyleIDs" );
|
||||
f_DB_CheckUserAuthority = (DB_CHECKUSERAUTHORITY)GetProcAddress( g_hDBDll, "DB_CheckUserAuthority" );
|
||||
f_DB_SetStyleCheck = (DB_SETSTYLECHECK)GetProcAddress( g_hDBDll, "DB_SetStyleCheck" );
|
||||
f_DB_GetCommonQnA = (DB_GETCOMMONQNA)GetProcAddress( g_hDBDll, "DB_GetCommonQnA" );
|
||||
f_DB_GetUserQnA = (DB_GETUSERQNA)GetProcAddress( g_hDBDll, "DB_GetUserQnA" );
|
||||
f_DB_GetNotice = (DB_GETNOTICE)GetProcAddress( g_hDBDll, "DB_GetNotice" );
|
||||
f_DB_SubmitQuestion = (DB_SUBMITQUESTION)GetProcAddress( g_hDBDll, "DB_SubmitQuestion" );
|
||||
f_DB_InsertSong = (DB_INSERTSONG)GetProcAddress( g_hDBDll, "DB_InsertSong" );
|
||||
f_DB_GetStyleUpdateListNew = (DB_GETSTYLEUPDATELISTNEW)GetProcAddress( g_hDBDll, "DB_GetStyleUpdateListNew" );
|
||||
f_DB_GetShareUpdateList = (DB_GETSHAREUPDATELIST)GetProcAddress( g_hDBDll, "DB_GetShareUpdateList" );
|
||||
f_DB_GetCheckUpdateList = (DB_GETCHECKUPDATELIST)GetProcAddress( g_hDBDll, "DB_GetCheckUpdateList" );
|
||||
f_DB_GetStyleInfoNew = (DB_GETSTYLEINFONEW)GetProcAddress( g_hDBDll, "DB_GetStyleInfoNew" );
|
||||
f_DB_UpdateStyle = (DB_UPDATESTYLE)GetProcAddress( g_hDBDll, "DB_UpdateStyle" );
|
||||
f_DB_CheckPayment = (DB_CHECKPAYMENT)GetProcAddress( g_hDBDll, "DB_CheckPayment" );
|
||||
f_DB_ConfirmPayment = (DB_CONFIRMPAYMENT)GetProcAddress( g_hDBDll, "DB_ConfirmPayment" );
|
||||
f_DB_StyleScore = (DB_STYLESCORE)GetProcAddress( g_hDBDll, "DB_StyleScore" );
|
||||
f_DB_InsertShareStyle = (DB_INSERTSHARESTYLE)GetProcAddress( g_hDBDll, "DB_InsertShareStyle" );
|
||||
f_DB_GetWebURL = (DB_GETWEBURL)GetProcAddress( g_hDBDll, "DB_GetWebURL" );
|
||||
#else
|
||||
f_DB_InitDatabases = (DB_INITDATABASES)DB_InitDatabases;
|
||||
f_DB_Release = (DB_RELEASE)DB_Release;
|
||||
f_DB_GetPath = (DB_GETPATH)DB_GetPath;
|
||||
f_DB_CleanVipLog = (DB_CLEANVIPLOG)DB_CleanVipLog;
|
||||
f_DB_GetClientVersion = (DB_GETCLIENTVERSION)DB_GetClientVersion;
|
||||
f_DB_GetClientTypeNumber = (DB_GETCLIENTTYPENUMBER)DB_GetClientTypeNumber;
|
||||
f_DB_GetStyleUpdateNumber = (DB_GETSTYLEUPDATENUMBER)DB_GetStyleUpdateNumber;
|
||||
f_DB_GetClientUpdateFlag = (DB_GETCLIENTUPDATEFLAG)DB_GetClientUpdateFlag;
|
||||
f_DB_PhoneCheck = (DB_PHONECHECK)DB_PhoneCheck;
|
||||
f_DB_Register = (DB_REGISTER)DB_Register;
|
||||
f_DB_Login = (DB_LOGIN)DB_Login;
|
||||
f_DB_Logoff = (DB_LOGOFF)DB_Logoff;
|
||||
f_DB_Verify = (DB_VERIFY)DB_Verify;
|
||||
f_DB_Purchase = (DB_PURCHASE)DB_Purchase;
|
||||
f_DB_InsertStyle = (DB_INSERTSTYLE)DB_InsertStyle;
|
||||
f_DB_GetStyleUpdateList = (DB_GETSTYLEUPDATELIST)DB_GetStyleUpdateList;
|
||||
f_DB_CheckStyleInfo = (DB_CHECKSTYLEINFO)DB_CheckStyleInfo;
|
||||
f_DB_GetRecomStyleIDs = (DB_GETRECOMSTYLEIDS)DB_GetRecomStyleIDs;
|
||||
f_DB_CheckUserAuthority = (DB_CHECKUSERAUTHORITY)DB_CheckUserAuthority;
|
||||
f_DB_SetStyleCheck = (DB_SETSTYLECHECK)DB_SetStyleCheck;
|
||||
f_DB_GetCommonQnA = (DB_GETCOMMONQNA)DB_GetCommonQnA;
|
||||
f_DB_GetUserQnA = (DB_GETUSERQNA)DB_GetUserQnA;
|
||||
f_DB_GetNotice = (DB_GETNOTICE)DB_GetNotice;
|
||||
f_DB_SubmitQuestion = (DB_SUBMITQUESTION)DB_SubmitQuestion;
|
||||
f_DB_InsertSong = (DB_INSERTSONG)DB_InsertSong;
|
||||
f_DB_GetStyleUpdateListNew = (DB_GETSTYLEUPDATELISTNEW)DB_GetStyleUpdateListNew;
|
||||
f_DB_GetShareUpdateList = (DB_GETSHAREUPDATELIST)DB_GetShareUpdateList;
|
||||
f_DB_GetCheckUpdateList = (DB_GETCHECKUPDATELIST)DB_GetCheckUpdateList;
|
||||
f_DB_GetStyleInfoNew = (DB_GETSTYLEINFONEW)DB_GetStyleInfoNew;
|
||||
f_DB_UpdateStyle = (DB_UPDATESTYLE)DB_UpdateStyle;
|
||||
f_DB_CheckPayment = (DB_CHECKPAYMENT)DB_CheckPayment;
|
||||
f_DB_ConfirmPayment = (DB_CONFIRMPAYMENT)DB_ConfirmPayment;
|
||||
f_DB_StyleScore = (DB_STYLESCORE)DB_StyleScore;
|
||||
f_DB_InsertShareStyle = (DB_INSERTSHARESTYLE)DB_InsertShareStyle;
|
||||
f_DB_GetWebURL = (DB_GETWEBURL)DB_GetWebURL;
|
||||
#endif
|
||||
|
||||
if( !( f_DB_InitDatabases && f_DB_Release && f_DB_GetClientVersion && f_DB_GetClientTypeNumber &&
|
||||
f_DB_GetStyleUpdateNumber && f_DB_GetClientUpdateFlag && f_DB_Login && f_DB_Verify &&
|
||||
f_DB_Purchase && f_DB_GetPath && f_DB_InsertStyle && f_DB_GetStyleUpdateList &&
|
||||
f_DB_CheckStyleInfo && f_DB_GetRecomStyleIDs && f_DB_CheckUserAuthority && f_DB_Register &&
|
||||
f_DB_SetStyleCheck && f_DB_GetCommonQnA && f_DB_GetUserQnA && f_DB_SubmitQuestion &&
|
||||
f_DB_GetNotice && f_DB_InsertSong && f_DB_GetStyleUpdateListNew && f_DB_GetStyleInfoNew &&
|
||||
f_DB_UpdateStyle && f_DB_CheckPayment && f_DB_ConfirmPayment && f_DB_StyleScore &&
|
||||
f_DB_InsertShareStyle && f_DB_GetShareUpdateList && f_DB_GetCheckUpdateList &&
|
||||
f_DB_Logoff && f_DB_CleanVipLog && f_DB_PhoneCheck && f_DB_GetWebURL )){
|
||||
|
||||
DebugPrint( "获取数据库访问函数失败, 程序终止!" );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
// int ret = f_DB_InitDatabases("localhost", "root", "168soft.xyz");
|
||||
// int ret = f_DB_InitDatabases("192.168.5.2", "root", "168soft.xyz");
|
||||
// int ret = f_DB_InitDatabases("printer", "root", "");
|
||||
// int ret = f_DB_InitDatabases("composemusic.xicp.net", "test", "123456");
|
||||
int ret = f_DB_InitDatabases("localhost", "root", "168soft.xyz");
|
||||
#else
|
||||
int ret = f_DB_InitDatabases("localhost", "root", "168soft.xyz");
|
||||
#endif
|
||||
if( ret==-1 ){
|
||||
DebugPrint( "初始化数据库失败, 程序终止!" );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
//载入网参模块
|
||||
g_hPMDll = LoadLibrary( PM_DLL );
|
||||
if( g_hPMDll==NULL ){
|
||||
DWORD dwRet = GetLastError();
|
||||
|
||||
DebugPrint( "载入网参模块失败,程序终止! errcode=%d", dwRet );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//获取网参函数
|
||||
f_PM_HandleParam = (PM_HandleParam)GetProcAddress( g_hPMDll, "PM_HandleParam" );
|
||||
#else
|
||||
f_PM_HandleParam = (PM_HANDLEPARAM)PM_HandleParam;
|
||||
#endif
|
||||
|
||||
if( !f_PM_HandleParam ){
|
||||
DebugPrint( "获取网参函数失败, 程序终止!" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FreeDB()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if( g_hPMDll ){
|
||||
FreeLibrary( g_hPMDll );
|
||||
g_hPMDll = NULL;
|
||||
}
|
||||
|
||||
if( g_hDBDll ){
|
||||
f_DB_Release();
|
||||
FreeLibrary( g_hDBDll );
|
||||
g_hDBDll = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
#ifndef DBInterfaceH
|
||||
#define DBInterfaceH
|
||||
|
||||
#include "ProCommon.h"
|
||||
#include "ServerInner.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#ifndef StoredProcedureH
|
||||
typedef struct tClientVersion
|
||||
{
|
||||
TSOFTWAREINFO swInfo;
|
||||
int iClientType;
|
||||
char strFilePath[256];
|
||||
|
||||
tClientVersion(){
|
||||
iClientType = 0;
|
||||
memset(strFilePath, 0, sizeof(strFilePath));
|
||||
}
|
||||
} TCLIENTVERSION, *PTCLIENTVERSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int iClientType;
|
||||
TVERSION version;
|
||||
} TTESTVERSION, *PTTESTVERSION;
|
||||
|
||||
typedef struct tQnAItem{
|
||||
UINT id;
|
||||
int iClientType[8];
|
||||
UINT state;
|
||||
UINT idUser;
|
||||
UINT dtUpdate;
|
||||
char strQuestion[320];
|
||||
char strAnswer[640];
|
||||
|
||||
tQnAItem(){
|
||||
id = state = idUser = dtUpdate = 0;
|
||||
memset( strQuestion, 0, 320 );
|
||||
memset( strAnswer, 0, 640 );
|
||||
memset( iClientType, -1, sizeof(int)*8 );
|
||||
}
|
||||
} TQNAITEM, *PTQNAITEM;
|
||||
typedef vector<TQNAITEM*> TQNAITEMLIST;
|
||||
|
||||
typedef struct tNoticeItem{
|
||||
UINT id;
|
||||
UINT iType;
|
||||
char strTitle[320];
|
||||
char strContent[640];
|
||||
|
||||
tNoticeItem(){
|
||||
id = iType = 0;
|
||||
memset( strTitle, 0, 320 );
|
||||
memset( strContent, 0, 640 );
|
||||
}
|
||||
} TNOTICEITEM, *PTNOTICEITEM;
|
||||
|
||||
typedef vector<TNOTICEITEM*> TNOTICEITEMLIST;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DLLAPI __stdcall
|
||||
#else //!_WIN32
|
||||
#define DLLAPI
|
||||
#endif
|
||||
|
||||
//Param function
|
||||
typedef DLLAPI DWORD (*PM_HANDLEPARAM)( DWORD dwParam1, DWORD dwParam2 );
|
||||
|
||||
//Database storeprocedure
|
||||
//---------------------------------------------------------获取目录-------------------------------------------------------------
|
||||
//--函数名: DB_GetPath
|
||||
//--功 能: 获取相关目录的绝对路径
|
||||
//--输 入:
|
||||
//-/chPathStyle: 调用时定义char[256]用于接收风格路径;
|
||||
//-/chPathFile: 调用时定义char[256]用于接收web路径;
|
||||
// chPathMusic: 调用时定义char[256]用于接收音乐路径;
|
||||
//--返 回: 成功返回 0 失败 -1
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETPATH)(char *chPathStyle, char *chPathFile, char* chPathMusic);
|
||||
|
||||
//--函数名: DB_CleanVipLog
|
||||
//--功 能: 清理VIP登录表
|
||||
//--输 入:
|
||||
//--返 回: 成功返回 0 失败 -1
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_CLEANVIPLOG)();
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_Register
|
||||
//--功 能: 软件用户注册
|
||||
//--输 入:
|
||||
//-/user:用户名
|
||||
//-/password:密码
|
||||
// isEmailOrMobile 捆绑邮箱或手机号 1=邮箱 2=手机号
|
||||
// idUser 用户ID
|
||||
// 返回strNickName用户昵称
|
||||
// iClientType 客户端类型
|
||||
//--返 回: 成功返回0;用户名已存在返回1;函数调用失败返回 -1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_REGISTER)(char *user, char *password, int isEmailOrMobile, int& idUser, char* strNickName, int iClinetType);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_PhoneCheck
|
||||
//--功 能: 短信验证
|
||||
//--输 入:
|
||||
// idDevice: 设备号
|
||||
// strPhone: 手机号
|
||||
// strCode: 验证码
|
||||
//--返 回: 成功返回0;验证失败返回1;函数调用失败返回 -1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_PHONECHECK)( char* idDevice, char* strPhone, char* strCode );
|
||||
|
||||
//-------------------------------------------------------------登陆-----------------------------------------------------------------
|
||||
//--函数名: Prc_user_checkLogin
|
||||
//--功 能: 登陆验证
|
||||
//--输 入:
|
||||
//--user:用户名
|
||||
//--password:密码
|
||||
// idDevice: 设备号
|
||||
//--chUserMsg:外部定义char[256] 用于接收帐户信息,以"|"分隔,如"3|sadwjf222|8308.44|100|1"
|
||||
// strNickName:用户昵称
|
||||
// strIconFile:用户头像文件名
|
||||
// iClientType 客户端类型
|
||||
//--返 回: 成功返回0;密码错误返回1;帐号不存在返回2;函数调用失败返回 -1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_LOGIN)(char *user, char *password, char *idDevice, TACCOUNTINFO *stUserMsg,
|
||||
char* strNickName, char* strIconFile, int iClinetType);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_Logoff
|
||||
//--功 能: 用户注销
|
||||
//--输 入:
|
||||
//-/idUser:用户号
|
||||
// idDevice: 设备号
|
||||
//--返 回: 成功返回0
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_LOGOFF)( int idUser, char *idDevice );
|
||||
|
||||
//------------------------------------检查更新-----------------------------------------------------------------
|
||||
//--函数名: DB_GetClientUpdateFlag
|
||||
//--功 能: 检查版本更新
|
||||
//--输 入:
|
||||
// iClientType: 客户端类型
|
||||
// clientVersion: 客户端版本信息;
|
||||
// idDevice: 设备号
|
||||
//--返 回:
|
||||
//--如果是最新版本,返回0;;
|
||||
//--如果有更新但不是强制更新,返回1;
|
||||
//--如果强制更新,返回2;
|
||||
//--非法版本,返回3;
|
||||
//--调用失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETCLIENTUPDATEFLAG)(int iClientType, TVERSION* clientVersion, char *idDevice);
|
||||
|
||||
//-------------------------------------------------------版本类型个数-----------------------------------------------------------
|
||||
//--函数名: getClientTypeNum
|
||||
//--功 能: 获取版本类型个数
|
||||
//--输 入:
|
||||
//--返 回:
|
||||
//--①成功返回版本类型个数 N >= 1
|
||||
//--②失败 -1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETCLIENTTYPENUMBER)();
|
||||
|
||||
//-------------------------------------------------------版本类型信息-----------------------------------------------------------
|
||||
//--函数名: getClientVersion
|
||||
//--功 能: 获取多个版本类型的信息
|
||||
//--输 入:
|
||||
//--aVersion:
|
||||
//--nArraySize:个数
|
||||
//--返 回:
|
||||
//--①成功返回0
|
||||
//--②失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETCLIENTVERSION)(TCLIENTVERSION aVersion[], int nArraySize);
|
||||
|
||||
|
||||
//
|
||||
//-------------------------------------------------------------更新风格数目-----------------------------------------------------------------
|
||||
//--函数名: DB_GetStyleUpdateNumber
|
||||
//--功 能: 获取风格更新数目
|
||||
//--输 入:
|
||||
//--chCltTime: Client上次更新时间点(YEAR<<16)+(MON<<8)+DAY),
|
||||
//--UpdataNum:调用时定义 int 变量 用于接收检测到的更新总数
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETSTYLEUPDATENUMBER)(int tCltTime, int *UpdataNum);
|
||||
|
||||
//---------------------------------------------------------保存鉴权-------------------------------------------------------------
|
||||
//--函数名: Prc_user_verify
|
||||
//--功 能: 保存鉴权,显示用到的风格列表,以及实际价格和VIP价格,如果余额充足,支付完成后可保存,如果余额不足,则提示,并引导冲值的方式
|
||||
//--输 入:
|
||||
//--dwStyleID:风格ID数组
|
||||
//--nStyleID :风格个数
|
||||
//--dStyleOriginPrice: 定义double[ nStyleID ]数组接收每个个风格的实际价格
|
||||
//--StyleCurrentPrice:定义double[ nStyleID ]数组接收每个个风格的应付价格
|
||||
//--dBalance: 定义double变量接收余额
|
||||
//--返 回:
|
||||
//--①如果余额充足(通过本次鉴权)返回 0;
|
||||
//--②如果余额不足(未通过鉴权)返回 1;
|
||||
//--③如果调用失败返回-1;
|
||||
// userID无效(未通过鉴权)返回2
|
||||
// styleID无效(未通过鉴权)返回3,同时在相应的styleoriginprice填写-1;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_VERIFY)( int nUserID,
|
||||
int dwStyleID[],
|
||||
int nStyleID,
|
||||
int aStyleOriginCost[],
|
||||
int aStyleCurrentCost[],
|
||||
int *nBalance);
|
||||
|
||||
//---------------------------------------------------------支 付-------------------------------------------------------------
|
||||
//--函数名: Prc_user_purchase
|
||||
//--功 能: 支付
|
||||
//--输 入:
|
||||
//--userID:用户号
|
||||
//--dwStyleID:风格ID数组
|
||||
//--nStyleID :风格个数
|
||||
//--nBalance:调用时定义int变量用于接收帐户余额
|
||||
//iapType: 支付方式 0=个人账户支付,1=中移动iap
|
||||
//--返 回:
|
||||
//--①(余额充足)购买成功返回0;
|
||||
//--②(余额不足)购买失败返回1;
|
||||
//--③调用失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (* DB_PURCHASE)(int nUserID, int dwStyleID[],int nStyleID, int *nBalance, int iapType);
|
||||
|
||||
//--------------------------------------------------------新增风格数据--------------------------------------------------------------
|
||||
//--函数名: DB_InsertStyle
|
||||
//--功 能: 新增风格数据
|
||||
//--输 入:
|
||||
// iType 新增类型,0=待审核,1=发布
|
||||
// pStyleInfo 风格信息
|
||||
//--返回:成功返回风格ID,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_INSERTSTYLE)( int iType, TMAKESTYLEINFO* pStyleInfo ); //新增风格数据
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_InsertShareStyle
|
||||
//--功 能: 新增分享风格数据
|
||||
//--输 入:
|
||||
// pInfo 风格信息
|
||||
//--返回:成功返回风格ID,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_INSERTSHARESTYLE)( TSTYLESHARE* pInfo ); //新增分享风格信息
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetStyleUpdataList
|
||||
//--功 能: 获取风格更新数目
|
||||
//--输 入:
|
||||
//iClientType: 客户端类型,<3为伴奏魔方,4=Checker
|
||||
//tUpdateTime: 更新时间点,如"2012-02-01" (高16位表示年 接下来饿8位表示月 低8位表示日),返回最新更新时间
|
||||
//UpdataNum:调用时定义 int 变量 用于接收检测到的更新总数
|
||||
//aUpdate:返回的列表数据,外部分配,外部释放
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETSTYLEUPDATELIST)(int iClientType, int* tUpdateTime, int *UpdataNum, TSTYLEUPDATE0 aUpdate[] );
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetStyleUpdateListNew
|
||||
//--功 能: 获取风格更新数目新接口
|
||||
//--输 入:
|
||||
//tUpdateTime: 更新时间点,如"2012-02-01" (高16位表示年 接下来饿8位表示月 低8位表示日),返回最新更新时间
|
||||
//UpdataNum:调用时定义 int 变量 用于接收检测到的更新总数
|
||||
//aUpdate:返回的列表数据,外部分配,外部释放
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETSTYLEUPDATELISTNEW)(int* tUpdateTime, int *UpdataNum, TSTYLEUPDATE aUpdate[] );
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetShareUpdataList
|
||||
//--功 能: 获取分享风格更新数目
|
||||
//--输 入:
|
||||
//tUpdateDate: 更新时间点,如"2012-02-01" (高16位表示年 接下来饿8位表示月 低8位表示日),返回最新更新时间
|
||||
//UpdataNum:调用时定义 int 变量 用于接收检测到的更新总数
|
||||
//aUpdate: 返回的列表数据,内部分配,外部释放
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETSHAREUPDATELIST)(int* tUpdateDate, int *nListSize, TSHAREUPDATE aUpdate[] );
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetCheckUpdataList
|
||||
//--功 能: 获取分享风格更新数目
|
||||
//--输 入:
|
||||
//tUpdateDate: 更新时间点,如"2012-02-01" (高16位表示年 接下来饿8位表示月 低8位表示日),返回最新更新时间
|
||||
//UpdataNum:调用时定义 int 变量 用于接收检测到的更新总数
|
||||
//aUpdate: 返回的列表数据,内部分配,外部释放
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETCHECKUPDATELIST)(int* tUpdateDate, int *nListSize, TCHECKUPDATE aUpdate[] );
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_CheckStyleInfo
|
||||
//--功 能: 确认风格信息有效性
|
||||
//--输 入:
|
||||
//iType: 风格类型 1=发布风格 2=临时风格 3=共享风格
|
||||
//idStyle: 风格ID
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_CHECKSTYLEINFO)( int iType, int idStyle );
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetStyleInfoNew
|
||||
//--功 能: 获取风格信息
|
||||
//--输 入:
|
||||
//iClientType: 客户端类型,<3为伴奏魔方,4=Checker
|
||||
//idStyle: 风格ID
|
||||
//pInfo:返回风格信息
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETSTYLEINFONEW)(int iClientType, int idStyle, TSTYLEDETAIL* pInfo );
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetRecomStyleIDs
|
||||
//--功 能: 获取推荐风格ID列表
|
||||
//--输 入:
|
||||
//idCount:调用时定义 int 变量 用于接收检测到的id总数
|
||||
//lstID:返回的列表数据,外部分配,外部释放
|
||||
//--返 回: 成功返回0; 失败返回-1;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (* DB_GETRECOMSTYLEIDS)( int* idCount, int lstID[] );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_CheckUserAuthority
|
||||
//--功 能: 获取用户权限
|
||||
//--输 入:
|
||||
//idUser:用户ID
|
||||
//anthority:查询权限
|
||||
//--返 回: 无权限返回0; 失败返回-1;有权限返回非零值
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_CHECKUSERAUTHORITY)( int idUser, int authority );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_SetStyleCheck
|
||||
//--功 能: 设置风格审核结果
|
||||
//--输 入:
|
||||
// idChecker: 审核者ID
|
||||
// idStyle: 临时风格ID
|
||||
// score: 评分 0=未通过
|
||||
// strMsg: 审核信息,审核通过时忽略
|
||||
//--返 回: 成功返回发布风格ID,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_SETSTYLECHECK)( int idUser, int idStyle, int score, char* strMsg );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetCommonQnA
|
||||
//--功 能: 查询常见问题
|
||||
//--输 入:
|
||||
// dtUpdate 最后更新时间
|
||||
// listSize 输入问题个数
|
||||
// listQA 返回问题数组
|
||||
//--返 回: 成功返回问题个数,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETCOMMONQNA)( int dtUpdate, int nListSize, TQNAITEM listQA[] );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetUserQnA
|
||||
//--功 能: 查询用户提问
|
||||
//--输 入:
|
||||
// idNum 待查询ID个数
|
||||
// idList 待查询ID
|
||||
// idUser 用户ID
|
||||
// iClientType 客户端类型
|
||||
// dtUpdate 更新时间
|
||||
// listSize 输入listQA大小
|
||||
// listQA 返回问题列表
|
||||
//--返 回: 成功返回问题个数,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETUSERQNA)( int idNum, int idList[], int idUser, int iClientType, int dtUpdate,
|
||||
int nListSize, TQNAITEM listQA[] );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_SubmitQuestion
|
||||
//--功 能: 提交问题
|
||||
//--输 入:
|
||||
// idUser: 提交者ID
|
||||
// iClientType: 客户端类型
|
||||
// strMsg: 提交信息
|
||||
// strVersion: 客户端版本
|
||||
//--返 回: 成功返回问题ID,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_SUBMITQUESTION)( int idUser, int iClientType, char* strMsg, char* strVersion );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetNotice
|
||||
//--功 能: 查询系统公告或用户通知
|
||||
//--输 入:
|
||||
// listSize 输入通知个数
|
||||
// listNotece 返回通知数组
|
||||
// idUser 查询用户号
|
||||
//--返 回: 成功返回公告个数,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETNOTICE)( int nListSize, TNOTICEITEM listNotice[], UINT idUser );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_InsertSong
|
||||
//--功 能: 新增上传歌曲
|
||||
//--输 入:
|
||||
//--idUser 用户号
|
||||
// iClientType 客户端类型
|
||||
//--pSongInfo 歌曲信息
|
||||
//--nSongSize 歌曲文件大小
|
||||
//--path 歌曲文件路径
|
||||
//--strCover 缺省封面
|
||||
//--location 文件存放盘符,空不填写
|
||||
//--返回:成功返回歌曲ID,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_INSERTSONG)(int idUser, int iClientType, TSONGINFO0* pSongInfo, int nSongSize,
|
||||
char* path, char* strCover, char* location );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_UpdateStyle
|
||||
//--功 能: 修改风格数据
|
||||
//--输 入: idStyle 风格ID
|
||||
//--pStyleInfo 风格信息
|
||||
//--返回:成功返回风格ID,失败返回-1
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_UPDATESTYLE)( UINT idStyle, TMAKESTYLEINFO* pStyleInfo );
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_CheckPayment
|
||||
//--功 能: 检查支付
|
||||
//--输 入:
|
||||
//idUser:用户号
|
||||
//iOperation: 操作号 0=使用 1=编辑
|
||||
//dwStyleID:风格ID数组
|
||||
//nStyleCount :风格个数
|
||||
//pCost: 接收积分消耗
|
||||
//pBalance: 接收用户积分余额
|
||||
//pFee: 接收功能费
|
||||
//--返 回:
|
||||
//--①如果余额充足(可以完成本次购买)返回 0;
|
||||
//--②如果余额不足(不能完成本次购买)返回 1;
|
||||
//--③如果调用失败返回-1;
|
||||
//--④如果用户无效,返回2;
|
||||
//--⑤如果有不存在的风格,返回3;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_CHECKPAYMENT)(int iClientType, UINT idUser, int iOperation, int nStyleCount, UINT dwStyleID[], int* pCost, int *pBalance, int *pFee);
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_ConfirmPayment
|
||||
//--功 能: 确认支付
|
||||
//--输 入:
|
||||
// iClientType 客户端类型
|
||||
//idUser:用户号
|
||||
//iOperation: 操作号 0=使用 1=编辑
|
||||
//nStyleCount :风格个数
|
||||
//dwStyleID:风格ID数组
|
||||
//nPaidCount :已支付风格个数
|
||||
//dwPaidID:已支付风格ID数组
|
||||
//pBalance: 接收用户积分余额
|
||||
//--返 回:
|
||||
//--①如果余额充足(可以完成本次购买)返回 0;
|
||||
//--②如果余额不足(不能完成本次购买)返回 1;
|
||||
//--③如果调用失败返回-1;
|
||||
//--④如果用户无效,返回2;
|
||||
//--⑤如果有不存在的风格,返回3;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_CONFIRMPAYMENT)(int iClientType, UINT idUser, int iOperation, int nStyleCount, UINT dwStyleID[],
|
||||
int nPaidCount, UINT dwPaidID[], int *pBalance);
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_StyleScore
|
||||
//--功 能: 风格评分
|
||||
//--输 入:
|
||||
// iType 风格类型 1=发布风格 2=临时风格 3=共享风格
|
||||
// idStyle:风格ID
|
||||
// pScore:风格当前评分
|
||||
// bGet:获取/设置
|
||||
//--返 回: 错误号
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_STYLESCORE)( int iType, UINT idStyle, int *pScore, bool bGet);
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//--函数名: DB_GetWebURL
|
||||
//--功 能: 获取网络地址
|
||||
//--输 入:
|
||||
//-/iPage: 请求页面编号
|
||||
// strURL: 接收网络地址
|
||||
//--返 回: 成功返回0
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
typedef DLLAPI int (*DB_GETWEBURL)( int iPage, char *strURL );
|
||||
|
||||
|
||||
extern PM_HANDLEPARAM f_PM_HandleParam;
|
||||
|
||||
extern DB_GETCLIENTVERSION f_DB_GetClientVersion;
|
||||
extern DB_GETCLIENTTYPENUMBER f_DB_GetClientTypeNumber;
|
||||
extern DB_GETPATH f_DB_GetPath;
|
||||
extern DB_CLEANVIPLOG f_DB_CleanVipLog;
|
||||
extern DB_GETSTYLEUPDATENUMBER f_DB_GetStyleUpdateNumber;
|
||||
extern DB_GETCLIENTUPDATEFLAG f_DB_GetClientUpdateFlag;
|
||||
extern DB_PHONECHECK f_DB_PhoneCheck;
|
||||
extern DB_REGISTER f_DB_Register;
|
||||
extern DB_LOGIN f_DB_Login;
|
||||
extern DB_LOGOFF f_DB_Logoff;
|
||||
extern DB_VERIFY f_DB_Verify;
|
||||
extern DB_PURCHASE f_DB_Purchase;
|
||||
extern DB_INSERTSTYLE f_DB_InsertStyle;
|
||||
extern DB_GETSTYLEUPDATELIST f_DB_GetStyleUpdateList;
|
||||
extern DB_CHECKSTYLEINFO f_DB_CheckStyleInfo;
|
||||
extern DB_GETRECOMSTYLEIDS f_DB_GetRecomStyleIDs;
|
||||
extern DB_CHECKUSERAUTHORITY f_DB_CheckUserAuthority;
|
||||
extern DB_SETSTYLECHECK f_DB_SetStyleCheck;
|
||||
extern DB_GETCOMMONQNA f_DB_GetCommonQnA;
|
||||
extern DB_GETUSERQNA f_DB_GetUserQnA;
|
||||
extern DB_SUBMITQUESTION f_DB_SubmitQuestion;
|
||||
extern DB_GETNOTICE f_DB_GetNotice;
|
||||
extern DB_INSERTSONG f_DB_InsertSong;
|
||||
extern DB_GETSTYLEUPDATELISTNEW f_DB_GetStyleUpdateListNew;
|
||||
extern DB_GETSHAREUPDATELIST f_DB_GetShareUpdateList;
|
||||
extern DB_GETCHECKUPDATELIST f_DB_GetCheckUpdateList;
|
||||
extern DB_GETSTYLEINFONEW f_DB_GetStyleInfoNew;
|
||||
extern DB_UPDATESTYLE f_DB_UpdateStyle;
|
||||
extern DB_CHECKPAYMENT f_DB_CheckPayment;
|
||||
extern DB_CONFIRMPAYMENT f_DB_ConfirmPayment;
|
||||
extern DB_STYLESCORE f_DB_StyleScore;
|
||||
extern DB_INSERTSHARESTYLE f_DB_InsertShareStyle;
|
||||
extern DB_GETWEBURL f_DB_GetWebURL;
|
||||
|
||||
#define DB_DLL "StoredProcedure.dll"
|
||||
#define PM_DLL "params.dll"
|
||||
|
||||
bool LoadDB();
|
||||
void FreeDB();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,466 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 模 块 名:DBService 文件名:DBService.c
|
||||
* 相关文件:DBService.h
|
||||
* 提交日期:2012.2.1 作 者:Alex
|
||||
* 版 本:0.1
|
||||
* 模块描述:
|
||||
* 本模块提供了Service程序的框架
|
||||
* main(int argc, char **argv);
|
||||
* service_ctrl(DWORD dwCtrlCode);
|
||||
* service_main(DWORD dwArgc, LPTSTR *lpszArgv);
|
||||
* CmdInstallService();
|
||||
* CmdRemoveService();
|
||||
* CmdDebugService(int argc, char **argv);
|
||||
* ControlHandler ( DWORD dwCtrlType );
|
||||
* GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
|
||||
* 修改记录:
|
||||
* 日 期 版本 修改人 修改内容
|
||||
*
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <process.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#define _DBSERVICE_C
|
||||
#include "DBService.h"
|
||||
#undef _DBSERVICE_C
|
||||
|
||||
// internal variables
|
||||
SERVICE_STATUS ssStatus; // current status of the service
|
||||
SERVICE_STATUS_HANDLE sshStatusHandle;
|
||||
DWORD dwErr = 0;
|
||||
TCHAR szErr[256];
|
||||
char SZDEPENDENCIES[10] = "";
|
||||
|
||||
// internal function prototypes
|
||||
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
|
||||
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
|
||||
VOID CmdInstallService();
|
||||
VOID CmdRemoveService();
|
||||
VOID CmdDebugService(int argc, char **argv);
|
||||
BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
|
||||
// main() either performs the command line task, or
|
||||
// call StartServiceCtrlDispatcher to register the
|
||||
// main service thread. When the this call returns,
|
||||
// the service has stopped, so exit.
|
||||
//
|
||||
//void _CRTAPI1 main(int argc, char **argv)
|
||||
int __cdecl _tmain(int argc, TCHAR *argv[])
|
||||
{
|
||||
SERVICE_TABLE_ENTRY dispatchTable[] = {
|
||||
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
if ( (argc > 1) &&((*argv[1] == '-') || (*argv[1] == '/')) ){
|
||||
int cmd = 0;
|
||||
|
||||
if ( _stricmp( "install", argv[1]+1 ) == 0 ){
|
||||
if( argc>2 ){
|
||||
strcpy( SZDEPENDENCIES, argv[2] );
|
||||
}
|
||||
|
||||
cmd = 1;
|
||||
}
|
||||
else if ( _stricmp( "remove", argv[1]+1 ) == 0 ){
|
||||
cmd = 2;
|
||||
}
|
||||
else if ( _stricmp( "debug", argv[1]+1 ) == 0 ){
|
||||
g_eDebug = 4;
|
||||
|
||||
if( argc>2 ){
|
||||
if ( _stricmp( "f", argv[2] ) == 0 ){
|
||||
g_eDebug = 1;
|
||||
}
|
||||
else if ( _stricmp( "n", argv[2] ) == 0 ){
|
||||
g_eDebug = 2;
|
||||
}
|
||||
else if ( _stricmp( "s", argv[2] ) == 0 ){
|
||||
g_eDebug = 3;
|
||||
}
|
||||
}
|
||||
|
||||
cmd = 3;
|
||||
}
|
||||
else if( _stricmp( "check", argv[1]+1 ) == 0 && argc>2 ){
|
||||
g_iChkStyle = atoi(argv[2]);
|
||||
|
||||
if( g_iChkStyle>0 ){
|
||||
g_eDebug = 3;
|
||||
cmd = 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( cmd==1 ){
|
||||
CmdInstallService();
|
||||
}
|
||||
else if( cmd==2 ){
|
||||
CmdRemoveService();
|
||||
}
|
||||
else if( cmd==3 ){
|
||||
CmdDebugService(argc, argv);
|
||||
}
|
||||
else{
|
||||
// this is just to be friendly
|
||||
printf( "%s -install <params> to install the service\n", SZAPPNAME );
|
||||
printf( "%s -remove to remove the service\n", SZAPPNAME );
|
||||
printf( "%s -debug <params> to run as a console app for debugging\n", SZAPPNAME );
|
||||
printf( "%s -check <index> to run as a console app for check style\n", SZAPPNAME );
|
||||
printf( "\nStartServiceCtrlDispatcher being called.\n" );
|
||||
printf( "This may take several seconds. Please wait.\n" );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if it doesn't match any of the above parameters
|
||||
// the service control manager may be starting the service
|
||||
// so we must call StartServiceCtrlDispatcher
|
||||
|
||||
if (!StartServiceCtrlDispatcher(dispatchTable))
|
||||
AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This routine performs the service initialization and then calls
|
||||
// the user defined ServiceStart() routine to perform majority
|
||||
// of the work.
|
||||
//
|
||||
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
||||
{
|
||||
// register our service control handler:
|
||||
sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
|
||||
|
||||
if (!sshStatusHandle)
|
||||
goto cleanup;
|
||||
|
||||
// SERVICE_STATUS members that don't change in example
|
||||
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||
ssStatus.dwServiceSpecificExitCode = 0;
|
||||
|
||||
// report the status to the service control manager.
|
||||
if (!ReportStatusToSCMgr(
|
||||
SERVICE_START_PENDING, // service state
|
||||
NO_ERROR, // exit code
|
||||
3000)) // wait hint
|
||||
goto cleanup;
|
||||
|
||||
ServiceStart( dwArgc, lpszArgv );
|
||||
|
||||
cleanup:
|
||||
// try to report the stopped status to the service control manager.
|
||||
if (sshStatusHandle)
|
||||
(VOID)ReportStatusToSCMgr(
|
||||
SERVICE_STOPPED,
|
||||
dwErr,
|
||||
0);
|
||||
printf( "%s stopped the service\n", SZAPPNAME );
|
||||
|
||||
// getchar();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//This function is called by the SCM whenever
|
||||
//ControlService() is called on this service.
|
||||
VOID WINAPI service_ctrl(DWORD dwCtrlCode)
|
||||
{
|
||||
// Handle the requested control code.
|
||||
//
|
||||
switch(dwCtrlCode){
|
||||
// Stop the service.
|
||||
// SERVICE_STOP_PENDING should be reported before
|
||||
// setting the Stop Event - hServerStopEvent - in
|
||||
// ServiceStop(). This avoids a race condition
|
||||
// which may result in a 1053 - The Service did not respond...
|
||||
// error.
|
||||
case SERVICE_CONTROL_STOP:
|
||||
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
|
||||
ServiceStop();
|
||||
return;
|
||||
// Update the service status.
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
break;
|
||||
// invalid control code
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Sets the current status of the service and
|
||||
//reports it to the Service Control Manager
|
||||
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
|
||||
DWORD dwWin32ExitCode,
|
||||
DWORD dwWaitHint)
|
||||
{
|
||||
static DWORD dwCheckPoint = 1;
|
||||
BOOL fResult = TRUE;
|
||||
|
||||
if( g_eDebug==0 ){
|
||||
if (dwCurrentState == SERVICE_START_PENDING)
|
||||
ssStatus.dwControlsAccepted = 0;
|
||||
else
|
||||
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
||||
|
||||
ssStatus.dwCurrentState = dwCurrentState;
|
||||
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
|
||||
ssStatus.dwWaitHint = dwWaitHint;
|
||||
|
||||
if ( ( dwCurrentState == SERVICE_RUNNING ) ||
|
||||
( dwCurrentState == SERVICE_STOPPED ) )
|
||||
ssStatus.dwCheckPoint = 0;
|
||||
else
|
||||
ssStatus.dwCheckPoint = dwCheckPoint++;
|
||||
|
||||
// Report the status of the service to the service control manager.
|
||||
//
|
||||
if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))){
|
||||
AddToMessageLog(TEXT("SetServiceStatus"));
|
||||
}
|
||||
}
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
//Allows any thread to log an error message
|
||||
VOID AddToMessageLog(LPTSTR lpszMsg)
|
||||
{
|
||||
TCHAR szMsg[256];
|
||||
HANDLE hEventSource;
|
||||
LPCTSTR lpszStrings[2];
|
||||
|
||||
// if ( g_eDebug<0 ){
|
||||
dwErr = GetLastError();
|
||||
|
||||
// Use event logging to log the error.
|
||||
//
|
||||
hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
|
||||
|
||||
_stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
|
||||
lpszStrings[0] = szMsg;
|
||||
lpszStrings[1] = lpszMsg;
|
||||
|
||||
if (hEventSource != NULL) {
|
||||
ReportEvent(hEventSource, // handle of event source
|
||||
EVENTLOG_ERROR_TYPE, // event type
|
||||
0, // event category
|
||||
0, // event ID
|
||||
NULL, // current user's SID
|
||||
2, // strings in lpszStrings
|
||||
0, // no bytes of raw data
|
||||
lpszStrings, // array of error strings
|
||||
NULL); // no raw data
|
||||
|
||||
(VOID) DeregisterEventSource(hEventSource);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Installs the service
|
||||
void CmdInstallService()
|
||||
{
|
||||
SC_HANDLE schService;
|
||||
SC_HANDLE schSCManager;
|
||||
|
||||
TCHAR szPath[512];
|
||||
DWORD dwBytesNeeded;
|
||||
|
||||
if ( GetModuleFileName( NULL, szPath, 512 ) == 0 ){
|
||||
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
|
||||
return;
|
||||
}
|
||||
|
||||
schSCManager = OpenSCManager(
|
||||
NULL, // machine (NULL == local)
|
||||
NULL, // database (NULL == default)
|
||||
SC_MANAGER_ALL_ACCESS // access required
|
||||
);
|
||||
|
||||
if ( schSCManager ){
|
||||
schService = CreateService(
|
||||
schSCManager, // SCManager database
|
||||
TEXT(SZSERVICENAME), // name of service
|
||||
TEXT(SZSERVICEDISPLAYNAME), // name to display
|
||||
SERVICE_ALL_ACCESS, // desired access
|
||||
SERVICE_WIN32_OWN_PROCESS, // service type
|
||||
SERVICE_AUTO_START, // start type
|
||||
SERVICE_ERROR_NORMAL, // error control type
|
||||
szPath, // service's binary
|
||||
NULL, // no load ordering group
|
||||
NULL, // no tag identifier
|
||||
TEXT(SZDEPENDENCIES), // dependencies
|
||||
NULL, // LocalSystem account
|
||||
NULL); // no password
|
||||
|
||||
if ( schService ){
|
||||
_tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
|
||||
|
||||
if( !StartService(schService, 0, NULL) ){
|
||||
printf("StartService failed (%d)\n", GetLastError());
|
||||
CloseServiceHandle(schService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QueryServiceStatusEx(
|
||||
schService, // handle to service
|
||||
SC_STATUS_PROCESS_INFO, // info level
|
||||
(LPBYTE) &ssStatus, // address of structure
|
||||
sizeof(SERVICE_STATUS_PROCESS), // size of structure
|
||||
&dwBytesNeeded ) ) // if buffer too small
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
else{
|
||||
_tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
|
||||
}
|
||||
|
||||
CloseServiceHandle(schSCManager);
|
||||
}
|
||||
else
|
||||
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
|
||||
}
|
||||
|
||||
// PURPOSE: Stops and removes the service
|
||||
void CmdRemoveService()
|
||||
{
|
||||
SC_HANDLE schService;
|
||||
SC_HANDLE schSCManager;
|
||||
|
||||
schSCManager = OpenSCManager(
|
||||
NULL, // machine (NULL == local)
|
||||
NULL, // database (NULL == default)
|
||||
SC_MANAGER_ALL_ACCESS // access required
|
||||
);
|
||||
|
||||
if ( schSCManager ){
|
||||
schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
|
||||
|
||||
if (schService){
|
||||
// try to stop the service
|
||||
if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) ){
|
||||
_tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
|
||||
Sleep( 1000 );
|
||||
|
||||
while( QueryServiceStatus( schService, &ssStatus ) ){
|
||||
if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ){
|
||||
_tprintf(TEXT("."));
|
||||
Sleep( 1000 );
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
|
||||
_tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
|
||||
else
|
||||
_tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
|
||||
|
||||
}
|
||||
|
||||
// now remove the service
|
||||
if( DeleteService(schService) )
|
||||
_tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
|
||||
else
|
||||
_tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
|
||||
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
else
|
||||
_tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
|
||||
|
||||
CloseServiceHandle(schSCManager);
|
||||
}
|
||||
else
|
||||
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Runs the service as a console application
|
||||
void CmdDebugService(int argc, char ** argv)
|
||||
{
|
||||
DWORD dwArgc;
|
||||
LPTSTR *lpszArgv;
|
||||
|
||||
#ifdef UNICODE
|
||||
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
|
||||
#else
|
||||
dwArgc = (DWORD) argc;
|
||||
lpszArgv = argv;
|
||||
#endif
|
||||
|
||||
_tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
|
||||
_tprintf(TEXT("Press Ctl+C to stop %s...\n"), TEXT(SZSERVICEDISPLAYNAME));
|
||||
SetConsoleCtrlHandler( ControlHandler, TRUE );
|
||||
|
||||
ServiceStart( dwArgc, lpszArgv );
|
||||
}
|
||||
|
||||
//Handled console control events
|
||||
BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
|
||||
{
|
||||
switch( dwCtrlType ){
|
||||
case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate
|
||||
case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
|
||||
_tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
|
||||
ServiceStop();
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//copies error message text to string
|
||||
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
|
||||
{
|
||||
DWORD dwRet;
|
||||
LPTSTR lpszTemp = NULL;
|
||||
|
||||
dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
LANG_NEUTRAL,
|
||||
(LPTSTR)&lpszTemp,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
// supplied buffer is not long enough
|
||||
if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
|
||||
lpszBuf[0] = TEXT('\0');
|
||||
else{
|
||||
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
|
||||
_stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
|
||||
}
|
||||
|
||||
if ( lpszTemp )
|
||||
LocalFree((HLOCAL) lpszTemp );
|
||||
|
||||
return lpszBuf;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 模 块 名:DBService 文件名:DBService.h
|
||||
* 相关文件:DBService.c
|
||||
* 提交日期:2012.2.1 作 者:Alex
|
||||
* 版 本:0.1
|
||||
* 修改记录:
|
||||
* 日 期 版本 修改人 修改内容
|
||||
*
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifndef DBServiceH
|
||||
#define DBServiceH
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _DBSERVICE_C
|
||||
int g_eDebug = 0;
|
||||
int g_iChkStyle = 0;
|
||||
#else
|
||||
extern int g_eDebug;
|
||||
extern int g_iChkStyle;
|
||||
#endif
|
||||
|
||||
#define SZAPPNAME "DBService"
|
||||
#define SZSERVICENAME "DBService"
|
||||
#define SZSERVICEDISPLAYNAME "DBService"
|
||||
#define SZSTOPEVENTNAME "DBService"
|
||||
|
||||
//user-defined ServiceStart and ServiceStop
|
||||
VOID ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
|
||||
VOID ServiceStop();
|
||||
|
||||
//Sets the current status of the service and
|
||||
//reports it to the Service Control Manager
|
||||
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
|
||||
|
||||
|
||||
//Allows any thread to log an error message
|
||||
void AddToMessageLog(LPTSTR lpszMsg);
|
||||
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,236 @@
|
||||
// DataReceiver.cpp: implementation of the CDataReceiver class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include "debug.h"
|
||||
#include "DataBuffers.h"
|
||||
#include "MessageDef.h"
|
||||
|
||||
#define MAX_BUFFER_NUM 500
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CDataReceiver
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CDataBufferManager::CDataBufferManager()
|
||||
:m_smProcess("mDBMProcess",1)
|
||||
{
|
||||
m_seqFileNo = 1;
|
||||
}
|
||||
|
||||
CDataBufferManager::~CDataBufferManager()
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
delete *iter;
|
||||
iter++;
|
||||
}
|
||||
|
||||
m_lstBuffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
int CDataBufferManager::NewDataBuffer( int idUser, int iType, int nDataSize, char* pData, int iClientType )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
DATABUFFER *pBuffer = (*iter);
|
||||
|
||||
if( pBuffer->iDataType==iType && pBuffer->idUser==idUser && pBuffer->iClientType==iClientType && pBuffer->nDataSize==nDataSize){
|
||||
pBuffer->idPack = pBuffer->nRecvSize = pBuffer->tSeconds = 0;
|
||||
// DebugPrint("repeat buffer %d (type: %d)", pBuffer->idBuffer, iType);
|
||||
|
||||
return -pBuffer->idBuffer;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_lstBuffers.size()>MAX_BUFFER_NUM ){
|
||||
DebugPrint("buffer full!!!");
|
||||
return ERR_BUFFER_NUM;
|
||||
}
|
||||
|
||||
//分配文件号
|
||||
int idFile = m_seqFileNo++;
|
||||
if( m_seqFileNo>MAX_BUFFER_ID ) m_seqFileNo = 1;
|
||||
|
||||
//创建DataBuffer
|
||||
DATABUFFER * pBuffer = new DATABUFFER;
|
||||
pBuffer->idUser = idUser;
|
||||
pBuffer->idBuffer = idFile;
|
||||
pBuffer->iDataType = iType;
|
||||
pBuffer->nDataSize = nDataSize;
|
||||
pBuffer->iClientType = iClientType;
|
||||
pBuffer->idPack = pBuffer->nRecvSize = pBuffer->tSeconds = 0;
|
||||
if( pData ){
|
||||
pBuffer->pData = pData;
|
||||
}
|
||||
else{
|
||||
pBuffer->pData = new char[nDataSize];
|
||||
}
|
||||
|
||||
m_lstBuffers.push_back( pBuffer );
|
||||
|
||||
return idFile;
|
||||
}
|
||||
|
||||
int CDataBufferManager::ReceiveData( int idBuffer, int idPack, int nSize, char* pNewData )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
if( (*iter)->idBuffer==idBuffer ){
|
||||
int ret = 0;
|
||||
|
||||
PDATABUFFER pBuffer = *iter;
|
||||
pBuffer->tSeconds = 0;
|
||||
|
||||
if( idPack > pBuffer->idPack ){
|
||||
ret = ERR_PACK_ID;
|
||||
}
|
||||
else if( idPack==pBuffer->idPack ){
|
||||
if( nSize > pBuffer->nDataSize - pBuffer->nRecvSize ){
|
||||
ret = ERR_DATA_SIZE;
|
||||
}
|
||||
else{
|
||||
memcpy( pBuffer->pData + pBuffer->nRecvSize, pNewData, nSize );
|
||||
pBuffer->nRecvSize += nSize;
|
||||
pBuffer->idPack++;
|
||||
|
||||
if( pBuffer->nRecvSize==pBuffer->nDataSize ){
|
||||
ret = ERR_DATA_END;
|
||||
/* ret = SaveFile( pBuffer );
|
||||
|
||||
delete[] pBuffer->pData;
|
||||
delete pBuffer;
|
||||
|
||||
m_lstBuffers.erase( iter );
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_DATA_ID;
|
||||
}
|
||||
|
||||
int CDataBufferManager::GetData( int idBuffer, int idPack, int& nSize, char*& pData )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
if( (*iter)->idBuffer==idBuffer ){
|
||||
int ret = 0;
|
||||
|
||||
PDATABUFFER pBuffer = *iter;
|
||||
pBuffer->tSeconds = 0;
|
||||
|
||||
if( idPack > pBuffer->idPack || idPack*MAX_PACK_SIZE > pBuffer->nDataSize ){
|
||||
ret = ERR_PACK_ID;
|
||||
}
|
||||
else if( idPack==pBuffer->idPack || idPack==pBuffer->idPack-1 ){
|
||||
if( (idPack+1)*MAX_PACK_SIZE<=pBuffer->nDataSize ){
|
||||
nSize = MAX_PACK_SIZE;
|
||||
}
|
||||
else{
|
||||
nSize = pBuffer->nDataSize % MAX_PACK_SIZE;
|
||||
}
|
||||
|
||||
pData = pBuffer->pData + idPack*MAX_PACK_SIZE;
|
||||
|
||||
if( idPack==pBuffer->idPack )
|
||||
pBuffer->idPack++;
|
||||
}
|
||||
else if( idPack==-1 ){ //客户端接收完成,删除数据
|
||||
// DebugPrint( "delete buffer %d due to complete", (*iter)->idBuffer );
|
||||
delete pBuffer;
|
||||
m_lstBuffers.erase( iter );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_DATA_ID;
|
||||
}
|
||||
|
||||
DATABUFFER * CDataBufferManager::GetBuffer( int idBuffer )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
if( (*iter)->idBuffer==idBuffer ){
|
||||
return *iter;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CDataBufferManager::DeleteBuffer( int idBuffer )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
if( (*iter)->idBuffer==idBuffer ){
|
||||
//DebugPrint( "delete buffer %d due to complete", (*iter)->idBuffer );
|
||||
delete *iter;
|
||||
|
||||
iter = m_lstBuffers.erase( iter );
|
||||
|
||||
break;
|
||||
}
|
||||
else{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDataBufferManager::OnTimer()
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstBuffers.size()>0 ){
|
||||
DATABUFFERLIST::iterator iter = m_lstBuffers.begin();
|
||||
while( iter!=m_lstBuffers.end() ){
|
||||
if( (*iter)->tSeconds>=30 ){ //超过半分钟无数据操作
|
||||
// DebugPrint( "delete buffer %d due to timeout (type: %d)", (*iter)->idBuffer, (*iter)->iDataType );
|
||||
delete *iter;
|
||||
|
||||
iter = m_lstBuffers.erase( iter );
|
||||
}
|
||||
else{
|
||||
(*iter)->tSeconds++;
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// DataReceiver.h: interface for the CDataReceiver class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DataBuffersH
|
||||
#define DataBuffersH
|
||||
|
||||
#include <string.h>
|
||||
#include "thread.h"
|
||||
|
||||
#define ERR_DATA_END 1
|
||||
#define ERR_DATA_ID -1
|
||||
#define ERR_PACK_ID -2
|
||||
#define ERR_DATA_SIZE -3
|
||||
#define ERR_BUFFER_NUM -4
|
||||
|
||||
#define DTYPE_STYLETEMP 0
|
||||
#define DTYPE_STYLEFILE 1
|
||||
#define DTYPE_STYLESTATE 2
|
||||
#define DTYPE_STYLEDATA 3
|
||||
#define DTYPE_QAUPDATE 4
|
||||
#define DTYPE_SONGFILE 5
|
||||
#define DTYPE_NTUPDATE 6
|
||||
#define DTYPE_STYLESHARE 7
|
||||
#define DTYPE_STYLEINFO 8
|
||||
#define DTYPE_ICONFILE 9
|
||||
|
||||
#define MAX_BUFFER_ID 0x7FFFFFF
|
||||
|
||||
typedef struct tagDataBuffer
|
||||
{
|
||||
int idBuffer;
|
||||
int idUser;
|
||||
int idPack;
|
||||
int iClientType;
|
||||
int iDataType;
|
||||
int nDataSize;
|
||||
int nRecvSize;
|
||||
int tSeconds;
|
||||
char* pData;
|
||||
|
||||
tagDataBuffer(){
|
||||
memset( this, 0, sizeof(tagDataBuffer) );
|
||||
}
|
||||
|
||||
~tagDataBuffer(){
|
||||
if( pData ){
|
||||
delete[] pData;
|
||||
pData = NULL;
|
||||
}
|
||||
}
|
||||
} DATABUFFER, *PDATABUFFER;
|
||||
|
||||
#include <list>
|
||||
using namespace std;
|
||||
typedef list< PDATABUFFER > DATABUFFERLIST;
|
||||
|
||||
class CDataBufferManager
|
||||
{
|
||||
public:
|
||||
CDataBufferManager();
|
||||
virtual ~CDataBufferManager();
|
||||
|
||||
int NewDataBuffer( int idUser, int iType, int nDataSize, char* pData=NULL, int iClientType=0 );
|
||||
int ReceiveData( int idBuffer, int idPack, int nSize, char* pNewData );
|
||||
int GetData( int idBuffer, int idPack, int& nSize, char*& pData);
|
||||
DATABUFFER * GetBuffer( int idBuffer );
|
||||
void DeleteBuffer( int idBuffer );
|
||||
void OnTimer();
|
||||
|
||||
private:
|
||||
CSema m_smProcess;
|
||||
int m_seqFileNo;
|
||||
DATABUFFERLIST m_lstBuffers;
|
||||
};
|
||||
|
||||
#endif // !defined(_DATARECEIVER_H_INCLUDED_)
|
||||
@@ -0,0 +1,383 @@
|
||||
#include<sys/types.h>
|
||||
#include<sys/socket.h>
|
||||
#include<arpa/inet.h>
|
||||
#include<unistd.h>
|
||||
#include<fcntl.h>
|
||||
#include<sys/epoll.h>
|
||||
#include<poll.h>
|
||||
#include<sys/timerfd.h>
|
||||
#include<map>
|
||||
|
||||
#include "Socket.h"
|
||||
#include "debug.h"
|
||||
#include "MessageHandle.h"
|
||||
#include "EpollThread.h"
|
||||
|
||||
#define TIMER_INTERVAL 5
|
||||
#define TIMER_EXPIRE 60
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//HandlerThread
|
||||
EpollHandler::HandlerThread::HandlerThread(EpollHandler* pHandler, CSema* pSema)
|
||||
: CThread(3000)
|
||||
{
|
||||
m_pHandler = pHandler;
|
||||
m_pSema = pSema;
|
||||
}
|
||||
|
||||
void EpollHandler::HandlerThread::Main()
|
||||
{
|
||||
while(!m_bExit){
|
||||
RECVBUFF* pRB = m_pHandler->GetBuff();
|
||||
if(pRB){
|
||||
// send(pRB->socket, pRB->buffer, pRB->buffsize, 0);
|
||||
TNETMESSAGE msgRequest;
|
||||
if( !m_bExit && ReadNetMessage( (unsigned char*)pRB->buffer, pRB->buffsize, &msgRequest )){
|
||||
TNETMESSAGE msgResponse;
|
||||
|
||||
struct sockaddr_in peerAddr;
|
||||
UINT peerLen = sizeof(peerAddr);
|
||||
if( getpeername(pRB->socket, (struct sockaddr *)&peerAddr, &peerLen)<0 ){
|
||||
DebugPrint("getpeername error: %d", errno);
|
||||
}
|
||||
|
||||
USHORT peerPort = ntohs(peerAddr.sin_port);
|
||||
if(msgRequest.iExtra < 0x0D00){
|
||||
memcpy(msgRequest.idDevice, &peerAddr.sin_addr, 4);
|
||||
memcpy(msgRequest.idDevice+4, &peerAddr.sin_port, 2);
|
||||
}
|
||||
else{
|
||||
memcpy(msgResponse.idDevice, msgRequest.idDevice, 6);
|
||||
}
|
||||
// if( msgRequest.eMessageType==e_versionRequest ){
|
||||
// DebugPrint( "CONNECT %s:%d type: TCP", inet_ntoa(peerAddr.sin_addr), peerPort );
|
||||
// }
|
||||
|
||||
if( !m_bExit && HandleRequest( &msgRequest, &msgResponse, peerAddr.sin_addr.s_addr, peerPort ) ){
|
||||
short nSize = DATA_BUFSIZE;
|
||||
if( !m_bExit && WriteNetMessage( (unsigned char*)pRB->buffer, nSize, &msgResponse ) ){
|
||||
if( send(pRB->socket, pRB->buffer, nSize, 0) == SOCKET_ERROR){
|
||||
DebugPrint("send() failed with error %d", errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete pRB;
|
||||
}
|
||||
else{
|
||||
m_pSema->ActP();
|
||||
}
|
||||
}
|
||||
|
||||
DebugPrint("EpollHandlerThread exit");
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//EpollHandler
|
||||
EpollHandler::EpollHandler()
|
||||
: m_smProcess(NULL, 0), m_smBuffers(NULL, 1)
|
||||
{
|
||||
for(int i=0; i<MAX_THREAD_NUM; i++){
|
||||
m_lstThreads[i] = new HandlerThread(this, &m_smProcess);
|
||||
m_lstThreads[i]->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
EpollHandler::~EpollHandler()
|
||||
{
|
||||
for(int i=0; i<MAX_THREAD_NUM; i++){
|
||||
delete m_lstThreads[i];
|
||||
m_lstThreads[i] = NULL;
|
||||
}
|
||||
|
||||
CMutexLock lockProcess( &m_smBuffers );
|
||||
while(m_lstBuff.size()){
|
||||
delete m_lstBuff.back();
|
||||
m_lstBuff.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void EpollHandler::AddBuff(RECVBUFF* pRB)
|
||||
{
|
||||
CMutexLock lockProcess( &m_smBuffers );
|
||||
m_lstBuff.push_back(pRB);
|
||||
|
||||
m_smProcess.ActV();
|
||||
}
|
||||
|
||||
RECVBUFF* EpollHandler::GetBuff()
|
||||
{
|
||||
CMutexLock lockProcess( &m_smBuffers );
|
||||
|
||||
RECVBUFF* pRB = NULL;
|
||||
if(!m_lstBuff.empty()){
|
||||
pRB = m_lstBuff.front();
|
||||
m_lstBuff.pop_front();
|
||||
}
|
||||
return pRB;
|
||||
}
|
||||
|
||||
void EpollHandler::Terminate()
|
||||
{
|
||||
//Set Thread Terminated status
|
||||
for(int i=0; i<MAX_THREAD_NUM; i++){
|
||||
m_lstThreads[i]->Terminate();
|
||||
}
|
||||
|
||||
//Release sema individully
|
||||
for(int i=0; i<MAX_THREAD_NUM; i++){
|
||||
m_smProcess.ActV();
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//EpollThread
|
||||
EpollThread::EpollThread()
|
||||
: CThread(5000)
|
||||
{
|
||||
m_pHandler = new EpollHandler();
|
||||
if(pipe(m_fdPipe)<0){
|
||||
DebugPrint("create pipe error: %d", errno);
|
||||
memset(m_fdPipe,0,sizeof(m_fdPipe));
|
||||
}
|
||||
}
|
||||
|
||||
EpollThread::~EpollThread()
|
||||
{
|
||||
if(!IsTerminated()){
|
||||
Terminate();
|
||||
}
|
||||
|
||||
if(m_pHandler){
|
||||
delete m_pHandler;
|
||||
m_pHandler = NULL;
|
||||
}
|
||||
|
||||
if(m_fdPipe[0]){
|
||||
close(m_fdPipe[0]);
|
||||
close(m_fdPipe[1]);
|
||||
}
|
||||
}
|
||||
|
||||
bool EpollThread::SetNoBlock(int fd)
|
||||
{
|
||||
int oldSocketFlag = fcntl(fd, F_GETFL, 0);
|
||||
int newSocketFlag = oldSocketFlag | O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, newSocketFlag) == -1){
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EpollThread::Terminate()
|
||||
{
|
||||
CThread::Terminate();
|
||||
|
||||
if(m_fdPipe[1])
|
||||
write(m_fdPipe[1], "0", 1);
|
||||
|
||||
if(m_pHandler)
|
||||
m_pHandler->Terminate();
|
||||
}
|
||||
|
||||
void EpollThread::Main()
|
||||
{
|
||||
//创建一个监听socket
|
||||
int listenfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
||||
if (listenfd == -1){
|
||||
DebugPrint("create listen socket error");
|
||||
return;
|
||||
}
|
||||
|
||||
//设置重用ip地址和端口号
|
||||
int on = 1;
|
||||
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char*)& on, sizeof(on));
|
||||
setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (char*)& on, sizeof(on));
|
||||
|
||||
//初始化服务器地址
|
||||
struct sockaddr_in bindaddr;
|
||||
bindaddr.sin_family = AF_INET;
|
||||
bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
bindaddr.sin_port = htons(LISTEN_PORT);
|
||||
|
||||
if (bind(listenfd, (struct sockaddr*) & bindaddr, sizeof(bindaddr)) == -1)
|
||||
{
|
||||
close(listenfd);
|
||||
DebugPrint("bind listen socker error.");
|
||||
return;
|
||||
}
|
||||
|
||||
//启动监听
|
||||
if (listen(listenfd, SOMAXCONN) == -1){
|
||||
close(listenfd);
|
||||
DebugPrint("listen error.");
|
||||
return;
|
||||
}
|
||||
|
||||
//创建epollfd
|
||||
int epollfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
if (epollfd == -1){
|
||||
DebugPrint("create epollfd error.");
|
||||
close(listenfd);
|
||||
return;
|
||||
}
|
||||
|
||||
epoll_event listen_fd_event;
|
||||
listen_fd_event.data.fd = listenfd;
|
||||
listen_fd_event.events = EPOLLIN;
|
||||
|
||||
//将监听sokcet绑定到epollfd上去
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &listen_fd_event) == -1){
|
||||
DebugPrint("epoll_ctl error");
|
||||
close(listenfd);
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_fdPipe[0]){
|
||||
struct epoll_event ev;
|
||||
ev.data.fd = m_fdPipe[0];
|
||||
ev.events = EPOLLIN; //水平触发方式,监听可读事件,即管道有数据可以读取了
|
||||
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, m_fdPipe[0], &ev)<0){
|
||||
DebugPrint("epoll_ctl_add pipe error: %d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
||||
if(timerfd!=-1 ){
|
||||
struct itimerspec newValue = {};
|
||||
newValue.it_interval.tv_sec = TIMER_INTERVAL;
|
||||
newValue.it_value.tv_sec = TIMER_INTERVAL;
|
||||
if(timerfd_settime(timerfd, 0, &newValue, NULL)==-1){
|
||||
DebugPrint("settime error");
|
||||
close(timerfd);
|
||||
}
|
||||
else{
|
||||
epoll_event timer_event;
|
||||
timer_event.data.fd = timerfd;
|
||||
timer_event.events = EPOLLIN;
|
||||
|
||||
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &timer_event)<0){
|
||||
DebugPrint("epoll_ctl_add timer error: %d", errno);
|
||||
close(timerfd);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
map<int, int> mapFds; //tcp连接组
|
||||
int maxCount = 0;
|
||||
epoll_event epoll_events[1024];
|
||||
char dataBuff[DATA_BUFSIZE];
|
||||
while(!m_bExit){
|
||||
int n = epoll_wait(epollfd, epoll_events, 1024, -1);
|
||||
if(n < 0){
|
||||
//被信号中断
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
//出错,退出
|
||||
DebugPrint("epoll exit with error: %d", errno);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n && !m_bExit; ++i) {
|
||||
if (epoll_events[i].data.fd == m_fdPipe[0]){ //exit signal
|
||||
DebugPrint("Got epoll exit signal");
|
||||
break;
|
||||
}
|
||||
else if (epoll_events[i].data.fd == timerfd){
|
||||
// DebugPrint("epoll timer on");
|
||||
uint64_t exp=0;
|
||||
if(read(timerfd, &exp, sizeof(uint64_t))!=sizeof(uint64_t)){
|
||||
close(timerfd);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for(auto it=mapFds.begin(); it!=mapFds.end();){
|
||||
it->second += TIMER_INTERVAL;
|
||||
|
||||
if( it->second >= TIMER_EXPIRE ){//空闲1分钟关闭
|
||||
close(it->first);
|
||||
it = mapFds.erase(it);
|
||||
// DebugPrint("close expired socket");
|
||||
}
|
||||
else{
|
||||
count++;
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
if(count>maxCount){
|
||||
DebugPrint("mapFds max size: %d", count);
|
||||
maxCount = count;
|
||||
}
|
||||
}
|
||||
else if (epoll_events[i].data.fd == listenfd){
|
||||
if(epoll_events[i].events & EPOLLIN){//侦听socket,接受新连接
|
||||
struct sockaddr_in clientaddr;
|
||||
socklen_t clientaddrlen = sizeof(clientaddr);
|
||||
int clientfd = accept4(listenfd, (struct sockaddr*)&clientaddr, &clientaddrlen, SOCK_NONBLOCK|SOCK_CLOEXEC);
|
||||
if (clientfd != -1){
|
||||
epoll_event client_event;
|
||||
client_event.data.fd = clientfd;
|
||||
client_event.events = EPOLLIN | EPOLLRDHUP;// | EPOLLET;
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, clientfd, &client_event) == -1){
|
||||
DebugPrint("add client fd to epollfd error");
|
||||
close(clientfd);
|
||||
}
|
||||
// DebugPrint("add client fd %d to epollfd", clientfd);
|
||||
// mapFds.insert(clientfd, 0);
|
||||
mapFds[clientfd] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (epoll_events[i].events & EPOLLRDHUP ) {
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) == -1){
|
||||
// DebugPrint("EPOLL_CTL_DEL clientfd %d by event %d", epoll_events[i].data.fd, epoll_events[i].events);
|
||||
// }
|
||||
// else{
|
||||
DebugPrint("EPOLL_CTL_DEL clientfd %d by event %d error", epoll_events[i].data.fd, epoll_events[i].events);
|
||||
}
|
||||
|
||||
close(epoll_events[i].data.fd);
|
||||
|
||||
mapFds.erase(mapFds.find(epoll_events[i].data.fd));
|
||||
}
|
||||
else if (epoll_events[i].events & EPOLLIN){ //事件可读
|
||||
// DebugPrint("client fd: %d recv data.", epoll_events[i].data.fd);
|
||||
|
||||
int m = recv(epoll_events[i].data.fd, dataBuff, DATA_BUFSIZE, 0);
|
||||
|
||||
// DebugPrint("read data size %d", m);
|
||||
|
||||
if( m>0 && ValidNetMessage((UCHAR*)dataBuff, m) ){
|
||||
RECVBUFF* pRB = new RECVBUFF;
|
||||
memcpy(pRB->buffer, dataBuff, m);
|
||||
pRB->socket = epoll_events[i].data.fd;
|
||||
pRB->buffsize = m;
|
||||
|
||||
m_pHandler->AddBuff(pRB);
|
||||
}
|
||||
else if (m <= 0 && errno != EWOULDBLOCK && errno != EINTR){ //对端关闭了连接,从epollfd上移除clientfd
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_DEL, epoll_events[i].data.fd, NULL) == -1){
|
||||
// DebugPrint("EPOLL_CTL_DEL clientfd %d normally", epoll_events[i].data.fd);
|
||||
// }
|
||||
// else{
|
||||
DebugPrint("EPOLL_CTL_DEL clientfd %d by EPOLLIN error", epoll_events[i].data.fd);
|
||||
}
|
||||
|
||||
close(epoll_events[i].data.fd);
|
||||
mapFds.erase(mapFds.find(epoll_events[i].data.fd));
|
||||
}
|
||||
|
||||
mapFds.find(epoll_events[i].data.fd)->second = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(epollfd);
|
||||
|
||||
DebugPrint("EPOLL main exit");
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <sys/socket.h>
|
||||
#include <list>
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
#define DATA_BUFSIZE 8192
|
||||
#define MAX_THREAD_NUM 10
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef unsigned int SOCKET;
|
||||
|
||||
typedef struct{
|
||||
SOCKET socket;
|
||||
char buffer[DATA_BUFSIZE];
|
||||
int buffsize;
|
||||
} RECVBUFF;
|
||||
|
||||
typedef list<RECVBUFF*> RECVBUFFLIST;
|
||||
|
||||
class EpollHandler
|
||||
{
|
||||
class HandlerThread : public CThread //inside class
|
||||
{
|
||||
private:
|
||||
EpollHandler* m_pHandler;
|
||||
CSema* m_pSema;
|
||||
public:
|
||||
HandlerThread(EpollHandler* pHandler, CSema* pSema);
|
||||
virtual void Main();
|
||||
};
|
||||
|
||||
private:
|
||||
RECVBUFFLIST m_lstBuff;
|
||||
HandlerThread* m_lstThreads[MAX_THREAD_NUM];
|
||||
CSema m_smProcess;
|
||||
CSema m_smBuffers;
|
||||
|
||||
public:
|
||||
EpollHandler();
|
||||
~EpollHandler();
|
||||
|
||||
void AddBuff(RECVBUFF*);
|
||||
RECVBUFF* GetBuff();
|
||||
void Terminate();
|
||||
};
|
||||
|
||||
class EpollThread : public CThread
|
||||
{
|
||||
private:
|
||||
EpollHandler* m_pHandler;
|
||||
int m_fdPipe[2];
|
||||
|
||||
bool SetNoBlock(int fd);
|
||||
public:
|
||||
EpollThread();
|
||||
~EpollThread();
|
||||
|
||||
virtual void Main();
|
||||
virtual void Terminate();
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
#include "INIParser.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
|
||||
//remove all blank space
|
||||
string &TrimString(string &str)
|
||||
{
|
||||
string::size_type pos = 0;
|
||||
while(str.npos != (pos = str.find(" ")))
|
||||
str = str.replace(pos, pos+1, "");
|
||||
return str;
|
||||
}
|
||||
//read in INI file and parse it
|
||||
int INIParser::ReadINI(string path)
|
||||
{
|
||||
ifstream in_conf_file(path.c_str());
|
||||
if(!in_conf_file) return 0;
|
||||
string str_line = "";
|
||||
string str_root = "";
|
||||
vector<ININode> vec_ini;
|
||||
while(getline(in_conf_file, str_line))
|
||||
{
|
||||
string::size_type left_pos = 0;
|
||||
string::size_type right_pos = 0;
|
||||
string::size_type equal_div_pos = 0;
|
||||
string str_key = "";
|
||||
string str_value = "";
|
||||
|
||||
//comment
|
||||
if(str_line.npos != (left_pos = str_line.find("#"))) str_line.erase(left_pos);
|
||||
if(str_line.npos != (left_pos = str_line.find(";"))) str_line.erase(left_pos);
|
||||
|
||||
//section
|
||||
if((str_line.npos != (left_pos = str_line.find("["))) && (str_line.npos != (right_pos = str_line.find("]"))))
|
||||
{
|
||||
//cout << str_line.substr(left_pos+1, right_pos-1) << endl;
|
||||
str_root = str_line.substr(left_pos+1, right_pos-1);
|
||||
}
|
||||
//key-value
|
||||
else if(str_line.npos != (equal_div_pos = str_line.find("=")))
|
||||
{
|
||||
str_key = str_line.substr(0, equal_div_pos);
|
||||
str_value = str_line.substr(equal_div_pos+1, str_line.size()-1);
|
||||
str_key = TrimString(str_key);
|
||||
str_value = TrimString(str_value);
|
||||
//cout << str_key << "=" << str_value << endl;
|
||||
}
|
||||
|
||||
if((!str_root.empty()) && (!str_key.empty()) && (!str_value.empty()))
|
||||
{
|
||||
ININode ini_node(str_root, str_key, str_value);
|
||||
vec_ini.push_back(ini_node);
|
||||
//cout << vec_ini.size() << endl;
|
||||
}
|
||||
}
|
||||
in_conf_file.close();
|
||||
in_conf_file.clear();
|
||||
//vector convert to map
|
||||
map<string, string> map_tmp;
|
||||
for(vector<ININode>::iterator itr = vec_ini.begin(); itr != vec_ini.end(); ++itr)
|
||||
{
|
||||
map_tmp.insert(pair<string, string>(itr->root, ""));
|
||||
}
|
||||
SubNode sn;
|
||||
for(map<string, string>::iterator itr = map_tmp.begin(); itr != map_tmp.end(); ++itr)
|
||||
{
|
||||
//cout << itr->first << endl;
|
||||
for(vector<ININode>::iterator sub_itr = vec_ini.begin(); sub_itr != vec_ini.end(); ++sub_itr)
|
||||
{
|
||||
if(sub_itr->root == itr->first)
|
||||
{
|
||||
//cout << sub_itr->key << "=" << sub_itr->value << endl;
|
||||
sn.InsertElement(sub_itr->key, sub_itr->value);
|
||||
}
|
||||
}
|
||||
map_ini.insert(pair<string, SubNode>(itr->first, sn));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
//get value by root and key
|
||||
string INIParser::GetValue(string root, string key)
|
||||
{
|
||||
map<string, SubNode>::iterator itr = map_ini.find(root);
|
||||
if(map_ini.end() != itr)
|
||||
{
|
||||
//if section found
|
||||
map<string, string>::iterator sub_itr = itr->second.sub_node.find(key);
|
||||
if(!(sub_itr->second).empty())
|
||||
return sub_itr->second;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
//write ini file
|
||||
int INIParser::WriteINI(string path)
|
||||
{
|
||||
ofstream out_conf_file(path.c_str());
|
||||
if(!out_conf_file)
|
||||
return -1;
|
||||
//cout << map_ini.size() << endl;
|
||||
for(map<string, SubNode>::iterator itr = map_ini.begin(); itr != map_ini.end(); ++itr)
|
||||
{
|
||||
//cout << itr->first << endl;
|
||||
out_conf_file << "[" << itr->first << "]" << endl;
|
||||
for(map<string, string>::iterator sub_itr = itr->second.sub_node.begin(); sub_itr != itr->second.sub_node.end(); ++sub_itr)
|
||||
{
|
||||
//cout << sub_itr->first << "=" << sub_itr->second << endl;
|
||||
out_conf_file << sub_itr->first << "=" << sub_itr->second << endl;
|
||||
}
|
||||
}
|
||||
out_conf_file.close();
|
||||
out_conf_file.clear();
|
||||
return 1;
|
||||
}
|
||||
//set value
|
||||
vector<ININode>::size_type INIParser::SetValue(string root, string key, string value)
|
||||
{
|
||||
map<string, SubNode>::iterator itr = map_ini.find(root);
|
||||
if(map_ini.end() != itr)
|
||||
itr->second.sub_node.insert(pair<string, string>(key, value));
|
||||
else
|
||||
{
|
||||
SubNode sn;
|
||||
sn.InsertElement(key, value);
|
||||
map_ini.insert(pair<string, SubNode>(root, sn));
|
||||
}
|
||||
return map_ini.size();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef INIParserH
|
||||
#define INIParserH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
//INI文件结点存储结构
|
||||
class ININode
|
||||
{
|
||||
public:
|
||||
ININode(string root, string key, string value)
|
||||
{
|
||||
this->root = root;
|
||||
this->key = key;
|
||||
this->value = value;
|
||||
}
|
||||
string root;
|
||||
string key;
|
||||
string value;
|
||||
};
|
||||
|
||||
//键值对结构体
|
||||
class SubNode
|
||||
{
|
||||
public:
|
||||
void InsertElement(string key, string value)
|
||||
{
|
||||
sub_node.insert(pair<string, string>(key, value));
|
||||
}
|
||||
map<string, string> sub_node;
|
||||
};
|
||||
|
||||
//主要的INIParser类
|
||||
class INIParser
|
||||
{
|
||||
public:
|
||||
int ReadINI(string path);
|
||||
string GetValue(string root, string key);
|
||||
vector<ININode>::size_type GetSize(){return map_ini.size();}
|
||||
vector<ININode>::size_type SetValue(string root, string key, string value);
|
||||
int WriteINI(string path);
|
||||
void Clear(){map_ini.clear();}
|
||||
private:
|
||||
map<string, SubNode> map_ini;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,333 @@
|
||||
#ifdef _WIN32
|
||||
#include "IOCmpltThread.h"
|
||||
#include "debug.h"
|
||||
#include "MessageDef.h"
|
||||
#include "MessageHandle.h"
|
||||
|
||||
HANDLE g_hCompletionPort;
|
||||
|
||||
CIOCmpltThread::CIOCmpltThread(unsigned int nStackSize)
|
||||
:CThread(nStackSize), m_smProcess("mProcess",1)
|
||||
{
|
||||
m_hListenSocket = NULL;
|
||||
g_hCompletionPort = NULL;
|
||||
m_nWorkerThreadNumbers = 0;
|
||||
|
||||
for(int i=0;i<MAX_PROCESSOR_COUNTER;i++)
|
||||
m_hWorkerThread[i] = NULL;
|
||||
}
|
||||
|
||||
void CIOCmpltThread::Main()
|
||||
{
|
||||
SOCKADDR_IN InternetAddr;
|
||||
SOCKET hAcceptSocket;
|
||||
SYSTEM_INFO SystemInfo;
|
||||
WSADATA wsaData;
|
||||
DWORD Ret;
|
||||
|
||||
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
|
||||
{
|
||||
DebugPrint("WSAStartup failed with error %d\n", Ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup an I/O completion port.
|
||||
|
||||
if ((g_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)
|
||||
{
|
||||
DebugPrint( "CreateIoCompletionPort failed with error: %d\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine how many processors are on the system.
|
||||
|
||||
GetSystemInfo(&SystemInfo);
|
||||
|
||||
// Create worker threads based on the number of processors available on the
|
||||
// system. Create two worker threads for each processor.
|
||||
|
||||
m_nWorkerThreadNumbers = SystemInfo.dwNumberOfProcessors*2+2;
|
||||
if( m_nWorkerThreadNumbers>MAX_PROCESSOR_COUNTER ){
|
||||
m_nWorkerThreadNumbers = MAX_PROCESSOR_COUNTER;
|
||||
}
|
||||
|
||||
for( int i=0; i<m_nWorkerThreadNumbers; i++ )
|
||||
{
|
||||
// Create a server worker thread and pass the completion port to the thread.
|
||||
DWORD ThreadID;
|
||||
m_hWorkerThread[i] = CreateThread(NULL, 0, ServerWorkerThread, this, 0, &ThreadID);
|
||||
}
|
||||
|
||||
// Create a listening socket
|
||||
|
||||
if ((m_hListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
|
||||
{
|
||||
DebugPrint("WSASocket() failed with error %d\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
InternetAddr.sin_family = AF_INET;
|
||||
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
InternetAddr.sin_port = htons(PORT);
|
||||
|
||||
if (bind(m_hListenSocket, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
|
||||
{
|
||||
DebugPrint("bind() failed with error %d\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare socket for listening
|
||||
|
||||
if (listen(m_hListenSocket, 20) == SOCKET_ERROR)
|
||||
{
|
||||
DebugPrint("listen() failed with error %d\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Accept connections and assign to the completion port.
|
||||
|
||||
while(!m_bExit){
|
||||
struct sockaddr_in saClient;
|
||||
int iClientSize = sizeof(saClient);
|
||||
if ((hAcceptSocket = WSAAccept(m_hListenSocket, (SOCKADDR*) &saClient, &iClientSize, NULL, 0)) == SOCKET_ERROR){
|
||||
DebugPrint("WSAAccept() failed with error %d\n", WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a socket information structure to associate with the socket
|
||||
LPCONTEXT_KEY lpContextKey = (LPCONTEXT_KEY)GlobalAlloc(GPTR, sizeof(CONTEXT_KEY));
|
||||
if( !lpContextKey ){
|
||||
DebugPrint("GlobalAlloc() failed with error %d\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Associate the accepted socket with the original completion port.
|
||||
ZeroMemory(&(lpContextKey->overlapped), sizeof(OVERLAPPED));
|
||||
lpContextKey->peerIp = saClient.sin_addr.S_un.S_addr;
|
||||
lpContextKey->peerPort = ntohs(saClient.sin_port);
|
||||
lpContextKey->socket = hAcceptSocket;
|
||||
lpContextKey->dataBuf.len = DATA_BUFSIZE;
|
||||
lpContextKey->dataBuf.buf = lpContextKey->buffer;
|
||||
lpContextKey->iOperation = COMPLETION_KEY_RECV;
|
||||
lpContextKey->nTimeCount = 0;
|
||||
|
||||
if (CreateIoCompletionPort((HANDLE)hAcceptSocket, g_hCompletionPort, (DWORD)lpContextKey, 0) == NULL){
|
||||
DebugPrint("CreateIoCompletionPort failed with error %d\n", GetLastError());
|
||||
closesocket( lpContextKey->socket );
|
||||
GlobalFree( lpContextKey );
|
||||
}
|
||||
else{
|
||||
// Create per I/O socket information structure to associate with the
|
||||
// WSARecv call below.
|
||||
m_lstContextKeys.push_back( lpContextKey );
|
||||
|
||||
DWORD RecvBytes;
|
||||
DWORD Flags;
|
||||
Flags = 0;
|
||||
if (WSARecv(hAcceptSocket, &(lpContextKey->dataBuf), 1, &RecvBytes, &Flags,
|
||||
&(lpContextKey->overlapped), NULL) == SOCKET_ERROR){
|
||||
if (WSAGetLastError() != ERROR_IO_PENDING){
|
||||
DebugPrint("1 WSARecv() failed with error %d\n", WSAGetLastError());
|
||||
FreeContextKey( lpContextKey );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CIOCmpltThread::Terminate()
|
||||
{
|
||||
CThread::Terminate();
|
||||
|
||||
int i;
|
||||
|
||||
if(m_hListenSocket)
|
||||
{
|
||||
closesocket(m_hListenSocket);
|
||||
m_hListenSocket = NULL;
|
||||
}
|
||||
|
||||
for( i=0; i<m_nWorkerThreadNumbers; i++ ){
|
||||
PostQueuedCompletionStatus(g_hCompletionPort,0,COMPLETION_KEY_SHUTDOWN,NULL);
|
||||
}
|
||||
|
||||
//关闭线程句柄
|
||||
for( i=0; i<m_nWorkerThreadNumbers; i++ ){
|
||||
if(m_hWorkerThread[i]){
|
||||
WaitForSingleObject( m_hWorkerThread[i], INFINITE );
|
||||
CloseHandle(m_hWorkerThread[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(g_hCompletionPort)
|
||||
{
|
||||
CloseHandle(g_hCompletionPort);
|
||||
g_hCompletionPort = NULL;
|
||||
}
|
||||
|
||||
if( m_lstContextKeys.size()>0 ){
|
||||
CONTEXTKEYLIST::iterator iter = m_lstContextKeys.begin();
|
||||
while( iter!=m_lstContextKeys.end() ){
|
||||
closesocket( (*iter)->socket );
|
||||
GlobalFree( *iter );
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
m_lstContextKeys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool CIOCmpltThread::IsValidContextKey( LPCONTEXT_KEY lpContextKey )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstContextKeys.size()>0 ){
|
||||
CONTEXTKEYLIST::iterator iter = m_lstContextKeys.begin();
|
||||
while( iter!=m_lstContextKeys.end() ){
|
||||
if( *iter==lpContextKey ){
|
||||
return true;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CIOCmpltThread::FreeContextKey( LPCONTEXT_KEY lpContextKey )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstContextKeys.size()>0 ){
|
||||
CONTEXTKEYLIST::iterator iter = m_lstContextKeys.begin();
|
||||
while( iter!=m_lstContextKeys.end() ){
|
||||
if( *iter==lpContextKey ){
|
||||
m_lstContextKeys.erase( iter );
|
||||
closesocket( lpContextKey->socket );
|
||||
GlobalFree( lpContextKey );
|
||||
|
||||
//DebugPrint( "Free client %d .\n", lpContextKey->socket );
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CIOCmpltThread::OnTimer()
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstContextKeys.size()>0 ){
|
||||
CONTEXTKEYLIST::iterator iter = m_lstContextKeys.begin();
|
||||
while( iter!=m_lstContextKeys.end() ){
|
||||
if( (*iter)->iOperation==COMPLETION_KEY_RECV && ++(*iter)->nTimeCount>=60 ){ //超过1分钟未接收到数据
|
||||
shutdown( (*iter)->socket, SD_BOTH );
|
||||
DebugPrint( "Client %d shutdown by timeout.\n", (*iter)->socket );
|
||||
closesocket( (*iter)->socket );
|
||||
(*iter)->iOperation = COMPLETION_KEY_SHUTDOWN;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI ServerWorkerThread(LPVOID lpVoid)
|
||||
{
|
||||
CIOCmpltThread* pThread = (CIOCmpltThread*)lpVoid;
|
||||
DWORD dwBytesTransferred = 0;
|
||||
LPOVERLAPPED lpOverlapped = NULL;
|
||||
LPCONTEXT_KEY lpContextKey = NULL;
|
||||
DWORD SendBytes, RecvBytes;
|
||||
DWORD Flags;
|
||||
BOOL bResult;
|
||||
|
||||
while(!pThread->IsTerminated()){
|
||||
bResult = GetQueuedCompletionStatus(g_hCompletionPort, &dwBytesTransferred,
|
||||
(LPDWORD)&lpContextKey, &lpOverlapped, INFINITE);
|
||||
if( !bResult ){
|
||||
int err = GetLastError();
|
||||
DebugPrint("GetQueuedCompletionStatus failed with error %d\n", err);
|
||||
|
||||
//if( err!=995 ){//&& pThread->IsValidContextKey( lpContextKey ) ){
|
||||
pThread->FreeContextKey( lpContextKey );
|
||||
//}
|
||||
}
|
||||
else{
|
||||
if( lpOverlapped==NULL && (DWORD)lpContextKey==COMPLETION_KEY_SHUTDOWN ){
|
||||
DebugPrint("ServerWorkThread shutdown.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( lpOverlapped!=NULL && pThread->IsValidContextKey(lpContextKey) ){
|
||||
ZeroMemory(&(lpContextKey->overlapped), sizeof(OVERLAPPED));
|
||||
if( lpContextKey->iOperation==COMPLETION_KEY_RECV ){
|
||||
if( dwBytesTransferred==0 ){
|
||||
DebugPrint("Client shutdown.\n" );
|
||||
pThread->FreeContextKey( lpContextKey );
|
||||
}
|
||||
else{
|
||||
lpContextKey->nTimeCount = 0; //计数器清零
|
||||
|
||||
TNETMESSAGE msgRequest;
|
||||
if( ReadNetMessage( (unsigned char*)lpContextKey->buffer, dwBytesTransferred, &msgRequest )){
|
||||
if( msgRequest.eMessageType==e_versionRequest ){
|
||||
char *pb=(char *)&(lpContextKey->peerIp);
|
||||
unsigned b1=(unsigned char)(*pb);
|
||||
unsigned b2=(unsigned char)(*(pb+1));
|
||||
unsigned b3=(unsigned char)(*(pb+2));
|
||||
unsigned b4=(unsigned char)(*(pb+3));
|
||||
DebugPrint( "CONNECT %d.%d.%d.%d:%d type: TCP\n", b1, b2, b3, b4, lpContextKey->peerPort );
|
||||
}
|
||||
|
||||
TNETMESSAGE msgResponse;
|
||||
if( HandleRequest( &msgRequest, &msgResponse, lpContextKey->peerIp, lpContextKey->peerPort ) ){
|
||||
int nSize = DATA_BUFSIZE;
|
||||
if( WriteNetMessage( (unsigned char*)lpContextKey->buffer, nSize, &msgResponse ) ){
|
||||
lpContextKey->iOperation=COMPLETION_KEY_SEND;
|
||||
lpContextKey->dataBuf.len = nSize;
|
||||
if( WSASend(lpContextKey->socket, &(lpContextKey->dataBuf), 1, &SendBytes, 0,
|
||||
&(lpContextKey->overlapped), NULL) == SOCKET_ERROR){
|
||||
if( WSAGetLastError() != ERROR_IO_PENDING){
|
||||
DebugPrint("WSASend() failed with error %d\n", WSAGetLastError());
|
||||
pThread->FreeContextKey( lpContextKey );
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Flags = 0;
|
||||
if (WSARecv(lpContextKey->socket, &(lpContextKey->dataBuf), 1, &RecvBytes, &Flags,
|
||||
&(lpContextKey->overlapped), NULL) == SOCKET_ERROR) {
|
||||
if( WSAGetLastError()!=ERROR_IO_PENDING ){
|
||||
DebugPrint("2 WSARecv() failed with error %d\n", WSAGetLastError());
|
||||
pThread->FreeContextKey( lpContextKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( lpContextKey->iOperation==COMPLETION_KEY_SEND ){
|
||||
lpContextKey->dataBuf.len = DATA_BUFSIZE;
|
||||
lpContextKey->iOperation = COMPLETION_KEY_RECV;
|
||||
Flags = 0;
|
||||
if (WSARecv(lpContextKey->socket, &(lpContextKey->dataBuf), 1, &RecvBytes, &Flags,
|
||||
&(lpContextKey->overlapped), NULL) == SOCKET_ERROR) {
|
||||
if( WSAGetLastError()!=ERROR_IO_PENDING ){
|
||||
DebugPrint("3 WSARecv() failed with error %d\n", WSAGetLastError());
|
||||
pThread->FreeContextKey( lpContextKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef IOCmpltThreadH
|
||||
#define IOCmpltThreadH
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <list>
|
||||
#include "Thread.h"
|
||||
|
||||
#define PORT 12071
|
||||
#define DATA_BUFSIZE 8192
|
||||
#define MAX_PROCESSOR_COUNTER 22 //最多定义22个处理器
|
||||
|
||||
enum SERVER_COMPLETE_KEY
|
||||
{
|
||||
COMPLETION_KEY_RECV = 0,
|
||||
COMPLETION_KEY_SEND = 1,
|
||||
COMPLETION_KEY_SHUTDOWN = 2,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SERVER_COMPLETE_KEY iOperation;
|
||||
int nTimeCount;
|
||||
SOCKET socket;
|
||||
OVERLAPPED overlapped;
|
||||
WSABUF dataBuf;
|
||||
char buffer[DATA_BUFSIZE];
|
||||
unsigned int peerIp;
|
||||
unsigned short peerPort;
|
||||
} CONTEXT_KEY, * LPCONTEXT_KEY;
|
||||
|
||||
using namespace std;
|
||||
typedef list< LPCONTEXT_KEY > CONTEXTKEYLIST;
|
||||
|
||||
class CIOCmpltThread : public CThread
|
||||
{
|
||||
public:
|
||||
void Main();
|
||||
CIOCmpltThread(unsigned int nStackSize);
|
||||
virtual void Terminate();
|
||||
bool IsValidContextKey( LPCONTEXT_KEY lpContextKey );
|
||||
void FreeContextKey( LPCONTEXT_KEY lpContextKey );
|
||||
void OnTimer();
|
||||
|
||||
private:
|
||||
SOCKET m_hListenSocket;
|
||||
HANDLE m_hWorkerThread[MAX_PROCESSOR_COUNTER];
|
||||
int m_nWorkerThreadNumbers;
|
||||
CSema m_smProcess;
|
||||
|
||||
CONTEXTKEYLIST m_lstContextKeys;
|
||||
};
|
||||
|
||||
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);
|
||||
|
||||
#endif //_IOCMPLTTHREAD_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
#ifndef MessageHandleH
|
||||
#define MessageHandleH
|
||||
|
||||
#include "MessageDef.h"
|
||||
|
||||
DWORD HandleVerifyParam( DWORD dwParam );
|
||||
bool HandleRequest( TNETMESSAGE* pRequest, TNETMESSAGE* pResponse, UINT ip, USHORT port, bool bUDP=false );
|
||||
int CreateStyle( int idUser, int iType, int nDataSize, char* pData );
|
||||
int GetStyleInfo( int iType, UINT id, int& nDataSize, char** ppData );
|
||||
int GetStyleData( int iType, UINT id, int& nDataSize, char** ppData );
|
||||
int PublishStyle( UINT idTemp, UINT idStyle );
|
||||
int GetStyleUserScore( int iType, UINT idStyle, UINT idUser, int* pScrUser, int* pScrAverage );
|
||||
int CreateSong( int idUser, int iClientType, int nDataSize, char* pData, TSHAREINFO* pInfo );
|
||||
int GetIconFile( char* strFile, int& nDataSize, char** ppData );
|
||||
|
||||
bool StyleTrans2Info( TSTYLEDETAIL& info, char* pData );
|
||||
bool ShareTrans2Info( TSTYLESHARE& info, char* pData );
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// 统计 PC pro 函数
|
||||
//void GetProCount(int& n826, int& nOth);
|
||||
//
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
#endif //_MESSAGEHANDLE_H_INCLUDED_
|
||||
@@ -0,0 +1,192 @@
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
//#include <process.h>
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
#include "MessageThread.h"
|
||||
#include "MessageHandle.h"
|
||||
|
||||
MHTHREADLIST g_lstMessageHandleThreads;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CUDPMessageReceiveThread
|
||||
//
|
||||
CUDPMessageReceiveThread::CUDPMessageReceiveThread(unsigned int nStackSize, CUDPSocket * pSocket)
|
||||
:CThread(nStackSize)
|
||||
{
|
||||
m_pSocket = pSocket;
|
||||
}
|
||||
|
||||
void CUDPMessageReceiveThread::Main()
|
||||
{
|
||||
TNETMESSAGE * pMsg = NULL;
|
||||
|
||||
while (!m_bExit && m_pSocket ){
|
||||
unsigned int nIpAddr;
|
||||
unsigned short nPort;
|
||||
|
||||
pMsg = ReadMessage( nIpAddr, nPort );
|
||||
|
||||
if( pMsg ){
|
||||
MHTHREADLIST::iterator iMT;
|
||||
for( iMT=g_lstMessageHandleThreads.begin(); iMT!=g_lstMessageHandleThreads.end(); iMT++ ){
|
||||
CMessageHandleThread * pThread = *iMT;
|
||||
if( pThread->IsSuspended() ){
|
||||
pThread->SetPeerAddress( nIpAddr, nPort );
|
||||
pThread->SetRequestMsg( pMsg );
|
||||
pThread->Resume();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(iMT==g_lstMessageHandleThreads.end()){ //无空闲线程
|
||||
delete pMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DebugPrint("退出网络消息接收线程");
|
||||
|
||||
ExitThread();
|
||||
}
|
||||
|
||||
void CUDPMessageReceiveThread::Terminate()
|
||||
{
|
||||
CThread::Terminate();
|
||||
|
||||
if( m_pSocket ){
|
||||
m_pSocket->Close();
|
||||
delete m_pSocket;
|
||||
m_pSocket = NULL;
|
||||
}
|
||||
|
||||
if(GetThreadID() && IsSuspended())
|
||||
Resume();
|
||||
|
||||
// Sleep( 10 );
|
||||
}
|
||||
|
||||
TNETMESSAGE * CUDPMessageReceiveThread::ReadMessage(unsigned int &nIpAddr,unsigned short &nPort)
|
||||
{
|
||||
int ret = m_pSocket->ReadFrom( m_sBuf, MAX_UDP_PACKET_SIZE, nIpAddr, nPort );
|
||||
if( ret==SOCKET_ERROR ){
|
||||
int err = WSAGetLastError();
|
||||
DebugPrint("读取网络消息失败:错误号 %d", err);
|
||||
}
|
||||
else if( ret==0 ){
|
||||
DebugPrint("网络连接已关闭");
|
||||
}
|
||||
else if(ValidNetMessage((UCHAR*)m_sBuf, ret)){
|
||||
TNETMESSAGE * pMsg = new TNETMESSAGE;
|
||||
if( ReadNetMessage( (unsigned char*)m_sBuf, ret, pMsg ) ){
|
||||
return pMsg;
|
||||
}
|
||||
else{
|
||||
delete pMsg;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMessageHandleThread
|
||||
//
|
||||
CMessageHandleThread::CMessageHandleThread(unsigned int nStackSize, CUDPSocket * pSocket)
|
||||
:CThread(nStackSize)
|
||||
{
|
||||
m_pSocket = pSocket;
|
||||
m_pRequestMsg = NULL;
|
||||
m_nPeerIp = 0;
|
||||
m_nPeerPort = 0;
|
||||
}
|
||||
|
||||
void CMessageHandleThread::Main()
|
||||
{
|
||||
while (!m_bExit && m_pSocket){
|
||||
if( m_pRequestMsg ){
|
||||
bool bIngnore = false;
|
||||
if(m_pRequestMsg->eMessageType!=e_connectRequest || m_pRequestMsg->iExtra>=0x0B00) //之前版本连接UDP可能有问题
|
||||
HandleGerneralMessage();
|
||||
|
||||
delete m_pRequestMsg;
|
||||
m_pRequestMsg = NULL;
|
||||
|
||||
}
|
||||
|
||||
Suspend();
|
||||
}
|
||||
|
||||
|
||||
DebugPrint("退出消息处理线程");
|
||||
|
||||
ExitThread();
|
||||
}
|
||||
|
||||
void CMessageHandleThread::HandleGerneralMessage()
|
||||
{
|
||||
TNETMESSAGE msgResponse;
|
||||
if(m_pRequestMsg->iExtra < 0x0D00){
|
||||
memcpy(m_pRequestMsg->idDevice, &m_nPeerIp, 4);
|
||||
memcpy(m_pRequestMsg->idDevice+4, &m_nPeerPort, 2);
|
||||
}
|
||||
else{
|
||||
memcpy(msgResponse.idDevice, m_pRequestMsg->idDevice, 6);
|
||||
}
|
||||
|
||||
if( HandleRequest( m_pRequestMsg, &msgResponse, m_nPeerIp, m_nPeerPort, true ) && !m_bExit){
|
||||
int nRet = SendMessage( &msgResponse );
|
||||
}
|
||||
}
|
||||
|
||||
void CMessageHandleThread::HandleUpdateMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void CMessageHandleThread::HandleUploadMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void CMessageHandleThread::Terminate()
|
||||
{
|
||||
CThread::Terminate();
|
||||
|
||||
// if( m_pSocket ){
|
||||
// m_pSocket->Close();
|
||||
// delete m_pSocket;
|
||||
// m_pSocket = NULL;
|
||||
// }
|
||||
|
||||
if(GetThreadID() && IsSuspended())
|
||||
Resume();
|
||||
|
||||
// Sleep( 10 );
|
||||
}
|
||||
|
||||
int CMessageHandleThread::SendMessage( TNETMESSAGE *pMsg )
|
||||
{
|
||||
char cMsg[MAX_MSG_LENGTH];
|
||||
short nSize = MAX_MSG_LENGTH;
|
||||
|
||||
if( !WriteNetMessage( (unsigned char*)cMsg, nSize, pMsg ) ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//发送数据
|
||||
int nSend = m_pSocket->SendTo( cMsg, nSize, m_nPeerIp, m_nPeerPort );
|
||||
// if( nSend==pMsg->nLength+10 ){
|
||||
// char *pb=(char *)&(m_nPeerIp);
|
||||
// unsigned b1=(unsigned char)(*pb);
|
||||
// unsigned b2=(unsigned char)(*(pb+1));
|
||||
// unsigned b3=(unsigned char)(*(pb+2));
|
||||
// unsigned b4=(unsigned char)(*(pb+3));
|
||||
// DebugPrint( "发送UDP消息到 %d.%d.%d.%d:%d 成功", b1, b2, b3, b4, m_nPeerPort );
|
||||
// }
|
||||
|
||||
return nSend;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef MessageThreadH
|
||||
#define MessageThreadH
|
||||
|
||||
#include "thread.h"
|
||||
#include "Socket.h"
|
||||
#include "MessageDef.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
// CUDPMessageReceiveThread
|
||||
//
|
||||
class CUDPMessageReceiveThread : public CThread
|
||||
{
|
||||
public:
|
||||
void Main();
|
||||
CUDPMessageReceiveThread(unsigned int nStackSize, CUDPSocket * pSocket);
|
||||
virtual void Terminate() ;
|
||||
|
||||
protected:
|
||||
CUDPSocket * m_pSocket;
|
||||
char m_sBuf[MAX_UDP_PACKET_SIZE];//实现一次读取需要的变量
|
||||
|
||||
TNETMESSAGE * ReadMessage(unsigned int &nIpAddr,unsigned short &nPort);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMessageHandleThread
|
||||
//
|
||||
class CMessageHandleThread : public CThread
|
||||
{
|
||||
public:
|
||||
void Main();
|
||||
CMessageHandleThread(unsigned int nStackSize, CUDPSocket * pSocket);
|
||||
virtual void Terminate() ;
|
||||
|
||||
void SetPeerAddress( unsigned int nIpAddr,unsigned short nPort ){
|
||||
m_nPeerIp = nIpAddr;
|
||||
m_nPeerPort = nPort;
|
||||
};
|
||||
|
||||
void SetRequestMsg( TNETMESSAGE* pMsg ){
|
||||
m_pRequestMsg = pMsg;
|
||||
};
|
||||
|
||||
protected:
|
||||
CUDPSocket * m_pSocket;
|
||||
unsigned int m_nPeerIp;
|
||||
unsigned short m_nPeerPort;
|
||||
|
||||
TNETMESSAGE * m_pRequestMsg;
|
||||
|
||||
void HandleGerneralMessage();
|
||||
void HandleUpdateMessage();
|
||||
void HandleUploadMessage();
|
||||
|
||||
int SendMessage( TNETMESSAGE * pMsg );
|
||||
};
|
||||
|
||||
#pragma warning( disable : 4786 )
|
||||
#include <list>
|
||||
using namespace std;
|
||||
|
||||
typedef list< CMessageHandleThread* > MHTHREADLIST;
|
||||
|
||||
#endif //_MESSAGETHREAD_H_
|
||||
@@ -0,0 +1,184 @@
|
||||
// ResponseManger.cpp: implementation of the CResponseManger class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "ResponseManager.h"
|
||||
#include "ServerInner.h"
|
||||
|
||||
#define MAX_RESPONSE_NUM 2000
|
||||
|
||||
int g_nMaxListSize = 0;
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CDataReceiver
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CResponseManager::CResponseManager()
|
||||
:m_smProcess("mRMProcess",1)
|
||||
{
|
||||
}
|
||||
|
||||
CResponseManager::~CResponseManager()
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
int nSize = m_lstResponses.size();
|
||||
DebugPrint( "Response remain size = %d", nSize );
|
||||
|
||||
if( nSize>0 ){
|
||||
TRESPONSELIST::iterator iter = m_lstResponses.begin();
|
||||
while( iter!=m_lstResponses.end() ){
|
||||
delete *iter;
|
||||
iter++;
|
||||
}
|
||||
|
||||
m_lstResponses.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool CResponseManager::NewResponse( int iExtra, TNETMESSAGE* pResponse )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstResponses.size()>MAX_RESPONSE_NUM || !pResponse ){
|
||||
return false;
|
||||
}
|
||||
|
||||
TRESPONSENODE * pNode = new TRESPONSENODE;
|
||||
pNode->iExtra = iExtra;
|
||||
pNode->iTimeCount = 0;
|
||||
memcpy( &(pNode->response), pResponse, pResponse->nLength+14 );
|
||||
// DebugPrint("Insert response for msg: 0x%X - %d", pResponse->eMessageType, iExtra);
|
||||
m_lstResponses.push_back( pNode );
|
||||
|
||||
if( m_lstResponses.size()>g_nMaxListSize ){
|
||||
g_nMaxListSize = m_lstResponses.size();
|
||||
|
||||
if( g_nMaxListSize%10==0 ){
|
||||
DebugPrint( "response list max size = %d.", g_nMaxListSize );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TNETMESSAGE* CResponseManager::GetResponse( TNETMESSAGE* pRequest )
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstResponses.size()>0 ){
|
||||
TRESPONSELIST::iterator iter = m_lstResponses.begin();
|
||||
while( iter!=m_lstResponses.end() ){
|
||||
if( (*iter)->response.eMessageType==pRequest->eMessageType+1 ){
|
||||
if( !memcmp(pRequest->idDevice, (*iter)->response.idDevice, 6) ){
|
||||
if( (*iter)->response.nSequenceNum==pRequest->nSequenceNum ){ //同一请求多次发送
|
||||
(*iter)->iTimeCount = 0;
|
||||
return &((*iter)->response);
|
||||
}
|
||||
else if(pRequest->eMessageType>=e_iconRequest //非时效性请求
|
||||
|| (*iter)->iTimeCount<5){ //或5秒内相同的请求
|
||||
int iExtra = 0;
|
||||
if(pRequest->eMessageType==e_webURLRequest){
|
||||
TIntRequest * pUrlReq = (TIntRequest*)pRequest->byMessageBody;
|
||||
iExtra = pUrlReq->iReq;
|
||||
}
|
||||
else if(pRequest->eMessageType==e_styleScoreRequest){
|
||||
UINT idStyle;
|
||||
int scrUser, iType = e_ST_Origin;
|
||||
|
||||
if( pRequest->nLength==sizeof(TStyleScoreRequest) ){
|
||||
TStyleScoreRequest * pSSReq = (TStyleScoreRequest*)pRequest->byMessageBody;
|
||||
idStyle = pSSReq->idStyle;
|
||||
iType = pSSReq->iType;
|
||||
scrUser = pSSReq->scrUser;
|
||||
}
|
||||
else{
|
||||
TStyleScoreRequest0 * pSSReq = (TStyleScoreRequest0*)pRequest->byMessageBody;
|
||||
idStyle = pSSReq->idStyle;
|
||||
scrUser = pSSReq->scrUser;
|
||||
}
|
||||
|
||||
iExtra = (idStyle<<16) + (iType<<8) + scrUser;
|
||||
|
||||
if(scrUser>0 && (iExtra&0xFFF0)==((*iter)->iExtra&0xFFF0) && iExtra!=(*iter)->iExtra ){
|
||||
delete *iter;
|
||||
iter = m_lstResponses.erase(iter);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(pRequest->eMessageType==e_styleInfoRequest){
|
||||
TStyleInfoRequest * pSIReq = (TStyleInfoRequest*)pRequest->byMessageBody;
|
||||
int iType = HIWORD( pSIReq->iType );
|
||||
if( iType==0 ){
|
||||
if( LOWORD( pSIReq->iType )==e_SM_Checker )
|
||||
iType = e_ST_Temp;
|
||||
else
|
||||
iType = e_ST_Origin;
|
||||
}
|
||||
iExtra = (iType<<16) + pSIReq->idStyle;
|
||||
}
|
||||
else if(pRequest->eMessageType==e_styleDataRequest){
|
||||
TStyleDataRequest * pSDReq = (TStyleDataRequest*)pRequest->byMessageBody;
|
||||
int iType = HIWORD( pSDReq->iType );
|
||||
if( iType==0 ){
|
||||
if( LOWORD( pSDReq->iType )==e_SM_Checker )
|
||||
iType = e_ST_Temp;
|
||||
else
|
||||
iType = e_ST_Origin;
|
||||
}
|
||||
iExtra = (iType<<16) + pSDReq->idStyle;
|
||||
}
|
||||
else if(pRequest->eMessageType==e_noticeUpdateRequest){
|
||||
TNoticeUpdateRequest * pNUReq = (TNoticeUpdateRequest*)pRequest->byMessageBody;
|
||||
iExtra = pNUReq->idUser;
|
||||
}
|
||||
else if(pRequest->eMessageType==e_qnaUpdateRequest){
|
||||
TQnAUpdateRequest * pQUReq = (TQnAUpdateRequest*)pRequest->byMessageBody;
|
||||
iExtra = (pQUReq->iClientType<<20) + pQUReq->idUser;
|
||||
}
|
||||
|
||||
if((*iter)->iExtra==iExtra){
|
||||
// DebugPrint("Got response for msg: 0x%X", pRequest->eMessageType);
|
||||
(*iter)->response.nSequenceNum = pRequest->nSequenceNum;
|
||||
(*iter)->iTimeCount = 0;
|
||||
return &((*iter)->response);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( pRequest->iExtra < 0x0D00 && (*iter)->response.nSequenceNum==pRequest->nSequenceNum
|
||||
&& ( pRequest->eMessageType==e_registerRequest || pRequest->eMessageType==e_qnaSubmitRequest )){
|
||||
(*iter)->iTimeCount = 0;
|
||||
return &((*iter)->response);
|
||||
}
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CResponseManager::OnTimer()
|
||||
{
|
||||
CMutexLock lockProcess( &m_smProcess );
|
||||
|
||||
if( m_lstResponses.size()>0 ){
|
||||
TRESPONSELIST::iterator iter = m_lstResponses.begin();
|
||||
while( iter!=m_lstResponses.end() ){
|
||||
if( ++((*iter)->iTimeCount)>=30 ){ //超过30秒无数据操作
|
||||
// DebugPrint("Delete response for msg: 0x%X", (*iter)->response.eMessageType);
|
||||
delete *iter;
|
||||
iter = m_lstResponses.erase( iter );
|
||||
}
|
||||
else{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// ResponseManager.h: interface for the CResponseManager class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ResponseManagerH
|
||||
#define ResponseManagerH
|
||||
|
||||
#include "thread.h"
|
||||
#include "MessageDef.h"
|
||||
|
||||
typedef struct tagResponse {
|
||||
TNETMESSAGE response;
|
||||
int iTimeCount;
|
||||
// UINT ip;
|
||||
// USHORT port;
|
||||
int iExtra;
|
||||
} TRESPONSENODE;
|
||||
|
||||
#include <list>
|
||||
using namespace std;
|
||||
typedef list< TRESPONSENODE* > TRESPONSELIST;
|
||||
|
||||
class CResponseManager
|
||||
{
|
||||
public:
|
||||
CResponseManager();
|
||||
virtual ~CResponseManager();
|
||||
|
||||
bool NewResponse( /*UINT ip, USHORT port, */ int iExtra, TNETMESSAGE* pResponse );
|
||||
TNETMESSAGE * GetResponse( /*UINT ip, USHORT port,*/ TNETMESSAGE* pRequest );
|
||||
void OnTimer();
|
||||
|
||||
private:
|
||||
CSema m_smProcess;
|
||||
TRESPONSELIST m_lstResponses;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,114 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 模 块 名:DBService 文件名:ServiceBody.c
|
||||
* 相关文件:DBService.h
|
||||
* 提交日期:2012.2.1 作 者:Alex
|
||||
* 版 本:0.1
|
||||
* 模块描述:
|
||||
* 本模块提供了用户定义的服务启动和停止程序
|
||||
* ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv);
|
||||
* ServiceStop();
|
||||
* 修改记录:
|
||||
* 日 期 版本 修改人 修改内容
|
||||
*
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <process.h>
|
||||
#include <tchar.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "DBService.h"
|
||||
#include "ServiceInit.h"
|
||||
|
||||
// this event is signalled when the service should end
|
||||
static HANDLE hServerStopEvent = NULL;
|
||||
DWORD g_unThreadId = 0;
|
||||
TCHAR strErr[256];
|
||||
|
||||
void ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
|
||||
{
|
||||
if (!ReportStatusToSCMgr(
|
||||
SERVICE_START_PENDING, // service state
|
||||
NO_ERROR, // exit code
|
||||
3000)) // wait hint
|
||||
{
|
||||
_tprintf(TEXT("ServiceStart failed - %s\n"), GetLastErrorText(strErr,256));
|
||||
return;
|
||||
}
|
||||
|
||||
char *parm = 0;
|
||||
if(dwArgc>=2)
|
||||
parm = lpszArgv[1];
|
||||
|
||||
HANDLE thread = (HANDLE)CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DBMain, NULL, 0, &g_unThreadId );
|
||||
|
||||
if( !thread ){
|
||||
_tprintf(TEXT("CreateThread failed - %s\n"), GetLastErrorText(strErr,256));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hServerStopEvent = CreateEvent(
|
||||
NULL, // no security attributes
|
||||
TRUE, // manual reset event
|
||||
FALSE, // not-signalled
|
||||
SZSTOPEVENTNAME); // named
|
||||
if ( hServerStopEvent == NULL){
|
||||
_tprintf(TEXT("CreateEvent(ServerStopEvent) failed - %s\n"), GetLastErrorText(strErr,256));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!ReportStatusToSCMgr(
|
||||
SERVICE_RUNNING, // service state
|
||||
NO_ERROR, // exit code
|
||||
0)) // wait hint
|
||||
{
|
||||
_tprintf(TEXT("ReportStatusToSCMgr failed - %s\n"), GetLastErrorText(strErr,256));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
WaitForSingleObject(hServerStopEvent, INFINITE);
|
||||
|
||||
// _tprintf(TEXT("hServerStopEvent signaled!\n"));
|
||||
cleanup:
|
||||
if( g_unThreadId!=0 ){
|
||||
PostThreadMessage( g_unThreadId, WM_CLOSE, 0, 0L );
|
||||
}
|
||||
|
||||
if( g_hEvServiceThread ){
|
||||
if(WAIT_OBJECT_0!=WaitForSingleObject(g_hEvServiceThread,15000))
|
||||
{
|
||||
TerminateThread(thread, 1);
|
||||
_tprintf(TEXT("TerminateThread %s\n"), GetLastErrorText(strErr,256));
|
||||
}
|
||||
else{
|
||||
// _tprintf(TEXT("g_hEvMcuThread signaled!\n"));
|
||||
}
|
||||
CloseHandle( g_hEvServiceThread );
|
||||
}
|
||||
|
||||
if( thread ){
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(thread,1000)){
|
||||
TerminateThread(thread, 2);
|
||||
}
|
||||
|
||||
CloseHandle( thread );
|
||||
_tprintf(TEXT("CloseHandle() %s\n"), GetLastErrorText(strErr,256));
|
||||
}
|
||||
|
||||
if(hServerStopEvent){
|
||||
CloseHandle(hServerStopEvent);
|
||||
}
|
||||
}
|
||||
|
||||
VOID ServiceStop()
|
||||
{
|
||||
if ( hServerStopEvent )
|
||||
SetEvent(hServerStopEvent);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,736 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 模 块 名:DBService 文件名:ServiceInit.c
|
||||
* 相关文件:ServiceInit.h
|
||||
* z提交日期:2012.2.1 作 者:Alex
|
||||
* 版 本:0.1
|
||||
* 模块描述:
|
||||
* 相当于事务处理模块的构造和析构模块
|
||||
* ServiceInit();
|
||||
* ServiceDeInit();
|
||||
* 修改记录:
|
||||
* 日 期 版本 修改人 修改内容
|
||||
*
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifdef _WIN32
|
||||
|
||||
#define _SERVICEINIT_CPP
|
||||
#include "IOCmpltThread.h"
|
||||
//#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <direct.h>
|
||||
|
||||
#include "DbService.h"
|
||||
#include "MessageThread.h"
|
||||
#include "ServiceInit.h"
|
||||
#include "debug.h"
|
||||
#include "DataBuffers.h"
|
||||
#include "ResponseManager.h"
|
||||
#include "DBInterface.h"
|
||||
//#define CTYPE_GBK 936
|
||||
//#define CTYPE_UTF8 65001
|
||||
|
||||
CUDPMessageReceiveThread * g_pMessageReceiveThread = NULL;
|
||||
CIOCmpltThread * g_pIOCmpltThread = NULL;
|
||||
CDataBufferManager* g_pDataBuffers = NULL;
|
||||
CResponseManager* g_pResponses = NULL;
|
||||
int g_aStyleRecomList[MAX_STYLE_NUM+1];
|
||||
TQNAITEM g_lstCommonQnA[200];
|
||||
TNOTICEITEM g_lstPublicNotice[MAX_NOTICE_NUM];
|
||||
int g_nCommonQnANum = 0, g_nPublicNoticeNum = 0;
|
||||
|
||||
HINSTANCE g_hDBAccessDll = NULL,
|
||||
g_hParamDll = NULL;
|
||||
|
||||
extern MHTHREADLIST g_lstMessageHandleThreads;
|
||||
|
||||
TCLIENTVERSION* g_pVersionClient = NULL;
|
||||
TTESTVERSION* g_pVersionClientTest = NULL;
|
||||
|
||||
int g_nClientTypeNum = 0,
|
||||
g_nClientTestNum = 0;
|
||||
HANDLE g_hEvClientCheck = NULL;
|
||||
char g_strStyleFileDir[256] = "";
|
||||
char g_strWebFileDir[256] = "";
|
||||
char g_strMusicFileDir[256] = "";
|
||||
char g_strMusicLocation[8] = "";
|
||||
char g_strServiceDir[256] = "";
|
||||
//UINT g_locale_ctype = 0;
|
||||
/*
|
||||
void UpdateStyleInfo()
|
||||
{
|
||||
typedef int (*CM_GetStyleTracksInfo)( int len, BYTE data[], char tracks[4][8][16][3] );
|
||||
|
||||
//加载ComposeModule
|
||||
HINSTANCE hStyleDll = LoadLibrary( "StyleUpdate.dll" );
|
||||
if( hStyleDll==NULL ){
|
||||
DWORD dwRet = GetLastError();
|
||||
|
||||
DebugPrint( "载入风格模块失败, 程序终止! errcode=%d", dwRet );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CM_GetStyleTracksInfo f_CM_GetStyleTracksInfo = (CM_GetStyleTracksInfo)GetProcAddress( hStyleDll, "CM_GetStyleTracksInfo" );
|
||||
|
||||
if( !( f_CM_GetStyleTracksInfo ) ){
|
||||
|
||||
DebugPrint( "获取风格模块访问函数失败, 程序终止!\n" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
char strFileName[256];
|
||||
char buf[20];
|
||||
|
||||
int id = 1;
|
||||
while( true ){
|
||||
//打开原风格文件
|
||||
strcpy( strFileName, g_strStyleFileDir );
|
||||
UINT nDir = ((UINT)id-1) >> 13;
|
||||
sprintf( buf, "%08X\\", nDir );
|
||||
strcat( strFileName, buf );
|
||||
|
||||
sprintf( buf, "%08X.YSF", id );
|
||||
strcat( strFileName, buf );
|
||||
|
||||
FILE *fp = fopen( strFileName, "r+b" );
|
||||
|
||||
if( !fp ){
|
||||
int err = GetLastError();
|
||||
DebugPrint( "修改完毕,或文件读取错误err=%d\n", err );
|
||||
|
||||
return;
|
||||
}
|
||||
else{
|
||||
//读取原风格信息
|
||||
fseek( fp, 0, SEEK_END );
|
||||
int len = ftell( fp );
|
||||
|
||||
int nDataSize = len - sizeof(TSTYLEINFO0);
|
||||
BYTE * pData = new BYTE[nDataSize];
|
||||
|
||||
TMAKESTYLEINFO infoNew;
|
||||
TSTYLEINFO0 infoOld;
|
||||
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
fread( &infoOld, 1, sizeof(TSTYLEINFO0), fp );
|
||||
fread( pData, 1, nDataSize, fp );
|
||||
|
||||
//读取轨道信息
|
||||
char tracks[4][8][16][3];
|
||||
int size = sizeof( tracks );
|
||||
memset( tracks, -1, size );
|
||||
|
||||
int err = f_CM_GetStyleTracksInfo( nDataSize, pData, tracks );
|
||||
if( 0==err ){
|
||||
//修改info
|
||||
// infoNew.idStyle = id;
|
||||
|
||||
memcpy( infoNew.detail.type, infoOld.detail.type, sizeof(infoOld.detail.type) );
|
||||
memcpy( infoNew.detail.chordRecom, infoOld.detail.chordRecom, sizeof(infoOld.detail.chordRecom) );
|
||||
memcpy( infoNew.detail.aIntroBars, infoOld.detail.aIntroBars, sizeof(infoOld.detail.aIntroBars) );
|
||||
memcpy( infoNew.detail.aEndingBars, infoOld.detail.aEndingBars, sizeof(infoOld.detail.aEndingBars) );
|
||||
|
||||
for( int s=0; s<4; s++ ){
|
||||
for( int i=0; i<8; i++ ){
|
||||
for( int j=0; j<16; j++ ){
|
||||
infoNew.detail.tracks[s][i][j].no = tracks[s][i][j][0];
|
||||
infoNew.detail.tracks[s][i][j].prog = tracks[s][i][j][1];
|
||||
infoNew.detail.tracks[s][i][j].vol = tracks[s][i][j][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = f_DB_UpdateStyle( id, &infoNew );
|
||||
if( 0==err ){
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
fwrite( &infoNew, 1, sizeof(TSTYLEINFO), fp );
|
||||
fwrite( pData, 1, nDataSize, fp );
|
||||
|
||||
// DebugPrint( "Style %d updating OK\n", infoNew.idStyle );
|
||||
}
|
||||
}
|
||||
|
||||
if( err!=0 ){
|
||||
DebugPrint( "Style %d updating failed! err=%d\n", id, err );
|
||||
}
|
||||
|
||||
delete[] pData;
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
id++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void ModifyStyleDesc()
|
||||
{
|
||||
char strFileName[256];
|
||||
char buf[20];
|
||||
// int ids[3] = {404,418,422};
|
||||
// char desc[3][120] = { "模仿周杰伦《东风破》的简单中国风,竖琴可换琵琶或古筝,鼓换电鼓",
|
||||
// "模仿王菲《闷》的摇滚风格,还原前间奏,乐器协调性是美中不足",
|
||||
// "麒麟谱,四不像,伪中国风。《红妆》编曲的收获,感谢花枝。" };
|
||||
|
||||
for( UINT i=g_iChkStyle; ; i++ ){
|
||||
char strFileName[256];
|
||||
char buf[20];
|
||||
|
||||
strcpy( strFileName, g_strStyleFileDir );
|
||||
|
||||
UINT nDir = (i-1) >> 13;
|
||||
sprintf( buf, "%08X\\", nDir );
|
||||
strcat( strFileName, buf );
|
||||
|
||||
sprintf( buf, "%08X.YSI", i );
|
||||
strcat( strFileName, buf );
|
||||
|
||||
FILE *fp = fopen( strFileName, "r+b" );
|
||||
|
||||
if( !fp ){
|
||||
int err = GetLastError();
|
||||
DebugPrint( "打开风格%d失败,err=%d\n", i, err );
|
||||
return;
|
||||
}
|
||||
else{
|
||||
short len = 0;
|
||||
|
||||
fread( &len, 1, sizeof(short), fp );
|
||||
|
||||
if( len>0 ){
|
||||
char* pData = new char[len];
|
||||
fread( pData, 1, len, fp );
|
||||
|
||||
TSTYLEDETAIL detail;
|
||||
int ret = StyleTrans2Detail( detail, len, (char*)pData );
|
||||
if( ret<0 ){
|
||||
DebugPrint( "Style %d size error\n", i );
|
||||
}
|
||||
else{
|
||||
if( ret>0 ){
|
||||
DebugPrint( "Trunc style %d %s\n", i, ret==1 ? "Author"
|
||||
: ret==2 ? "AtyleName"
|
||||
: "Description" );
|
||||
|
||||
// string ansiName;
|
||||
//
|
||||
// UTF8ToGBK( detail.strDescription, ansiName );
|
||||
// GBKToUTF8( desc[i], ansiName);
|
||||
// strcpy( detail.strDescription, ansiName.c_str() );
|
||||
|
||||
int size;
|
||||
ret = StyleDetail2Trans( detail, size, pData );
|
||||
if( ret>0 )
|
||||
DebugPrint( "Trunc style %d %s\n", i, ret==1 ? "Author"
|
||||
: ret==2 ? "AtyleName"
|
||||
: "Description" );
|
||||
|
||||
len = size;
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
fwrite( &len, 1, sizeof(short), fp );
|
||||
fwrite( pData, 1, len, fp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateLog()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
char szBufPath[MAX_PATH] = "";
|
||||
|
||||
sprintf( szBufPath, "%slog\\", g_strServiceDir );
|
||||
|
||||
if( _chdir(szBufPath) == -1)
|
||||
{
|
||||
_mkdir(szBufPath);
|
||||
}
|
||||
|
||||
sprintf( szBufPath, "%s%04d-%02d-%02d.log", szBufPath, st.wYear, st.wMonth, st.wDay);
|
||||
|
||||
DebugModuleClose();
|
||||
|
||||
int iDebug = g_eDebug>0 ? g_eDebug : 1;
|
||||
|
||||
DebugModuleInitialize( 0xFFFF, (EDPrintDest)iDebug, szBufPath );
|
||||
}
|
||||
|
||||
void GetStyleRecomList()
|
||||
{
|
||||
int tempList[MAX_STYLE_NUM+1];
|
||||
memset( tempList, 0, sizeof(int)*(MAX_STYLE_NUM+1) );
|
||||
int num = MAX_STYLE_NUM;
|
||||
int ret = f_DB_GetRecomStyleIDs( &num, tempList );
|
||||
|
||||
if( ret==0 ){
|
||||
tempList[MAX_STYLE_NUM] = num;
|
||||
memcpy( g_aStyleRecomList, tempList, sizeof(int)*(MAX_STYLE_NUM+1) );
|
||||
|
||||
DebugPrint( "Recommand style num : %d\n", num );
|
||||
}
|
||||
else{
|
||||
DebugPrint( "DB_GetRecomStyleIDs return %d\n", ret );
|
||||
}
|
||||
}
|
||||
|
||||
void GetCommonQnAList()
|
||||
{
|
||||
int dtUpdate = 0;
|
||||
for( int i=0; i<g_nCommonQnANum; i++ ){
|
||||
if( dtUpdate<g_lstCommonQnA[i].dtUpdate ){
|
||||
dtUpdate = g_lstCommonQnA[i].dtUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
g_nCommonQnANum = f_DB_GetCommonQnA( dtUpdate, g_nCommonQnANum, g_lstCommonQnA );
|
||||
|
||||
DebugPrint( "Common QnA num : %d\n", g_nCommonQnANum );
|
||||
}
|
||||
|
||||
void GetPublicNoticeList()
|
||||
{
|
||||
g_nPublicNoticeNum = f_DB_GetNotice( MAX_NOTICE_NUM, g_lstPublicNotice, 0 );
|
||||
|
||||
DebugPrint( "Public notice num : %d\n", g_nPublicNoticeNum );
|
||||
}
|
||||
|
||||
#define INI_FILE_NAME "DBService.ini"
|
||||
#define STR_TESTVERSION_SECTION "TEST_VERSIONS"
|
||||
#define STR_TESTVERSION "VERSIONS_STRING"
|
||||
FILETIME g_ftIniModify;
|
||||
|
||||
void ReadConfigParams()
|
||||
{
|
||||
char szBufPath[MAX_PATH] = "";
|
||||
sprintf( szBufPath, "%s%s", g_strServiceDir, INI_FILE_NAME );
|
||||
|
||||
HANDLE hFile = CreateFile( szBufPath, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if( hFile == INVALID_HANDLE_VALUE ){
|
||||
DebugPrint( "No ini file\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
FILETIME ftWrite;
|
||||
ret = GetFileTime(hFile, NULL, NULL, &ftWrite);
|
||||
|
||||
CloseHandle( hFile );
|
||||
|
||||
if( !ret ){
|
||||
DebugPrint( "Get ini file time error: %d\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
if( ftWrite.dwLowDateTime!=g_ftIniModify.dwLowDateTime
|
||||
|| ftWrite.dwHighDateTime!=g_ftIniModify.dwHighDateTime ){
|
||||
if( WAIT_OBJECT_0!=WaitForSingleObject( g_hEvClientCheck, INFINITE ) )
|
||||
return;
|
||||
|
||||
//printf( "retrive config.\n" );
|
||||
TTESTVERSION aVersion[10];
|
||||
int num = 0;
|
||||
char szBuf[32] = "";
|
||||
|
||||
ret = GetPrivateProfileString( STR_TESTVERSION_SECTION, STR_TESTVERSION, "", szBuf, 32, szBufPath );
|
||||
|
||||
if( ret>0 ){
|
||||
char *tokenPtr=strtok( szBuf, "|" );
|
||||
for( ; tokenPtr!=NULL; num++ ){
|
||||
int iInner, iMaj, iMin, iMod, iBuil;
|
||||
sscanf( tokenPtr, "%d,%d.%d.%d", &iInner, &iMaj, &iMin, &iMod );//, &iBuil );
|
||||
|
||||
aVersion[num].iClientType = iInner;
|
||||
aVersion[num].version.majorVersion = iMaj;
|
||||
aVersion[num].version.minorVersion = iMin;
|
||||
aVersion[num].version.modifyVersion = iMod;
|
||||
// aVersion[num].version.buildVersion = iBuil;
|
||||
|
||||
tokenPtr = strtok( NULL, "|" );
|
||||
}
|
||||
}
|
||||
|
||||
if( g_nClientTestNum>0 && g_nClientTestNum!=num ){
|
||||
delete[] g_pVersionClientTest;
|
||||
g_pVersionClientTest = NULL;
|
||||
}
|
||||
|
||||
g_nClientTestNum = num;
|
||||
|
||||
if( num>0 ){
|
||||
if( !g_pVersionClientTest ){
|
||||
g_pVersionClientTest = new TTESTVERSION[num];
|
||||
}
|
||||
|
||||
for( int i=0; i<num; i++ ){
|
||||
TTESTVERSION* pVersion = &(g_pVersionClientTest[i]);
|
||||
memcpy( pVersion, &aVersion[i], sizeof(TTESTVERSION) );
|
||||
|
||||
DebugPrint( "测试版本:%d.%d.%d\n软件内部编号:%d\n",
|
||||
pVersion->version.majorVersion, pVersion->version.minorVersion,
|
||||
pVersion->version.modifyVersion, //pVersion->version.buildVersion, //不设置构建版本
|
||||
pVersion->iClientType );
|
||||
}
|
||||
}
|
||||
else{
|
||||
DebugPrint( "No test version.\n" );
|
||||
}
|
||||
|
||||
SetEvent( g_hEvClientCheck );
|
||||
|
||||
g_ftIniModify.dwLowDateTime = ftWrite.dwLowDateTime;
|
||||
g_ftIniModify.dwHighDateTime = ftWrite.dwHighDateTime;
|
||||
}
|
||||
else{
|
||||
DebugPrint( "No config update.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
void GetClientUpdateVersion()
|
||||
{
|
||||
if( WAIT_OBJECT_0!=WaitForSingleObject( g_hEvClientCheck, INFINITE ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
int nOldTypeNum = g_nClientTypeNum;
|
||||
g_nClientTypeNum = f_DB_GetClientTypeNumber();
|
||||
|
||||
if( nOldTypeNum>0 && g_nClientTypeNum!=nOldTypeNum ){
|
||||
delete[] g_pVersionClient;
|
||||
g_pVersionClient = NULL;
|
||||
}
|
||||
|
||||
if( g_nClientTypeNum>0 ){
|
||||
if( !g_pVersionClient ){
|
||||
g_pVersionClient = new TCLIENTVERSION[g_nClientTypeNum];
|
||||
}
|
||||
|
||||
if( f_DB_GetClientVersion( g_pVersionClient, g_nClientTypeNum )>=0 ){
|
||||
for( int i=0; i<g_nClientTypeNum; i++ ){
|
||||
TCLIENTVERSION* pVersion = &(g_pVersionClient[i]);
|
||||
|
||||
string ansiDescribe;
|
||||
UTF8ToGBK( pVersion->swInfo.strDescribe, ansiDescribe );
|
||||
|
||||
DebugPrint( "软件内部编号:%d\n最新客户端版本:%d.%d.%d.%04d\n 发布时间:%d-%d-%d\n 文件大小:%dK\n 文件描述:%s\n",
|
||||
pVersion->iClientType,
|
||||
pVersion->swInfo.version.majorVersion, pVersion->swInfo.version.minorVersion,
|
||||
pVersion->swInfo.version.modifyVersion, pVersion->swInfo.version.buildVersion,
|
||||
pVersion->swInfo.tIssueDate>>16, (pVersion->swInfo.tIssueDate&0xFF00)>>8, (pVersion->swInfo.tIssueDate&0xFF),
|
||||
pVersion->swInfo.nFileSize, ansiDescribe.c_str() );
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
DebugPrint( "获取最新客户端版本信息失败!\n" );
|
||||
}
|
||||
}
|
||||
else if( g_nClientTypeNum<0 ){
|
||||
DebugPrint( "获取最新客户端类型数失败!\n" );
|
||||
}
|
||||
|
||||
SetEvent( g_hEvClientCheck );
|
||||
}
|
||||
|
||||
void OnTimerFunc( void *dummy )
|
||||
{
|
||||
CreateLog();
|
||||
// GetClientUpdateVersion();
|
||||
GetStyleRecomList();
|
||||
GetCommonQnAList();
|
||||
// GetPublicNoticeList();
|
||||
|
||||
DebugPrint( "OnTimerFunc exit.\n" );
|
||||
}
|
||||
|
||||
bool ServiceInit()
|
||||
{
|
||||
g_hEvServiceThread = CreateEvent(
|
||||
NULL, // no security attributes
|
||||
TRUE, // manual reset event
|
||||
FALSE, // not-signalled
|
||||
NULL); // no name
|
||||
|
||||
g_hEvClientCheck = CreateEvent(
|
||||
NULL, // no security attributes
|
||||
FALSE, // auto reset event
|
||||
TRUE, // signalled
|
||||
NULL); // no name
|
||||
|
||||
if( !(g_hEvServiceThread && g_hEvClientCheck )){
|
||||
return false;
|
||||
}
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
/*
|
||||
//获取本地编码格式
|
||||
char* locname = setlocale(LC_CTYPE, "");
|
||||
char* code = strchr( locname, '.' );
|
||||
//DebugPrint( "locale code: %s\n", code);
|
||||
if( !strcmp(code, ".936") || !strcmp(code, ".GBK") ){
|
||||
g_locale_ctype = CTYPE_GBK;
|
||||
}
|
||||
*/
|
||||
wVersionRequested = MAKEWORD( 2, 2 );
|
||||
|
||||
err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if ( err != 0 ) {
|
||||
// Tell the user that we could not find a usable
|
||||
// WinSock DLL.
|
||||
_tprintf(TEXT("CreateService failed - can't startup wsock.\n"));
|
||||
|
||||
if( g_hEvServiceThread ){
|
||||
CloseHandle( g_hEvServiceThread );
|
||||
g_hEvServiceThread = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//设置debug参数
|
||||
HKEY hRootKey;
|
||||
DWORD nFlag=1, dwLength=4;
|
||||
|
||||
if( ERROR_SUCCESS==RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\YHD\\ComposerService",
|
||||
0, KEY_ALL_ACCESS, &hRootKey ) ){
|
||||
if( RegQueryValueEx(hRootKey,"DebugFlag",NULL,NULL,(BYTE*)&nFlag,&dwLength)!=ERROR_SUCCESS ){
|
||||
RegSetValueEx(hRootKey,"DebugFlag",0,REG_DWORD,(BYTE*)&nFlag,4 );
|
||||
}
|
||||
RegCloseKey( hRootKey );
|
||||
}
|
||||
|
||||
char chTemp[2560];
|
||||
GetModuleFileName( NULL, chTemp, 256 );
|
||||
*(strrchr(chTemp, '\\')+1) = '\0';
|
||||
strcpy( g_strServiceDir, chTemp );
|
||||
//DebugModuleInitialize( 0xFFFF, (EDPrintDest)g_eDebug, NULL );
|
||||
CreateLog();
|
||||
//DebugPrint("DebugModuleInitialize success!\n");
|
||||
|
||||
//载入数据库访问模块
|
||||
if( !LoadDB() ){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// int ret = f_DB_InitDatabases("localhost", "root", "168soft.xyz");
|
||||
|
||||
f_DB_GetPath( g_strStyleFileDir, g_strWebFileDir, g_strMusicFileDir );
|
||||
DebugPrint( "Style_dir: %s\nWeb_dir: %s\nMusic_dir: %s\n", g_strStyleFileDir, g_strWebFileDir, g_strMusicFileDir );
|
||||
if( strlen(g_strMusicFileDir)>0 ){
|
||||
char* pos = strstr( g_strMusicFileDir, "File" )+4;
|
||||
if( pos[0]!='/' && pos[0]!='\\' ){
|
||||
int num;
|
||||
sscanf( pos, "%d", &num );
|
||||
sprintf( g_strMusicLocation, "%d", num );
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//修改风格信息专用
|
||||
//#ifdef _UPDATE
|
||||
if( g_iChkStyle>0 ){
|
||||
// UpdateStyleInfo();
|
||||
ModifyStyleDesc();
|
||||
return FALSE;
|
||||
}
|
||||
//#endif
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
GetClientUpdateVersion();
|
||||
memset( g_aStyleRecomList, 0, sizeof(int)*(MAX_STYLE_NUM+1) );
|
||||
GetStyleRecomList();
|
||||
|
||||
g_ftIniModify.dwLowDateTime = 0;
|
||||
g_ftIniModify.dwHighDateTime = 0;
|
||||
ReadConfigParams();
|
||||
|
||||
GetCommonQnAList();
|
||||
GetPublicNoticeList();
|
||||
|
||||
//创建数据接收
|
||||
g_pDataBuffers = new CDataBufferManager;
|
||||
|
||||
//创建消息响应管理
|
||||
g_pResponses = new CResponseManager;
|
||||
|
||||
//生成消息接收线程
|
||||
CUDPSocket * pSocket = new CUDPSocket( 12071 );
|
||||
|
||||
if( pSocket && pSocket->IsOpen() ){
|
||||
g_pMessageReceiveThread = new CUDPMessageReceiveThread( 3000, pSocket );
|
||||
g_pMessageReceiveThread->Resume();
|
||||
}
|
||||
|
||||
//生成消息处理线程池
|
||||
for( int i=0; i<20; i++ ){
|
||||
pSocket = new CUDPSocket();
|
||||
if( pSocket && pSocket->IsOpen() ){
|
||||
CMessageHandleThread* pThread = new CMessageHandleThread( 3000, pSocket );
|
||||
g_lstMessageHandleThreads.push_back( pThread );
|
||||
}
|
||||
}
|
||||
|
||||
//生成IOComplete线程
|
||||
g_pIOCmpltThread = new CIOCmpltThread(3000);
|
||||
g_pIOCmpltThread->Resume();
|
||||
|
||||
_tprintf(TEXT("Composer Service is running...\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServiceDeInit()
|
||||
{
|
||||
_tprintf(TEXT("Composer Service is stopping...\n"));
|
||||
|
||||
if( g_hEvClientCheck ){
|
||||
CloseHandle( g_hEvClientCheck );
|
||||
}
|
||||
|
||||
if( g_pVersionClient ){
|
||||
delete[] g_pVersionClient;
|
||||
g_pVersionClient = NULL;
|
||||
}
|
||||
|
||||
if( g_pMessageReceiveThread ){
|
||||
g_pMessageReceiveThread->Terminate();
|
||||
delete g_pMessageReceiveThread;
|
||||
g_pMessageReceiveThread = NULL;
|
||||
}
|
||||
|
||||
MHTHREADLIST::iterator iMT = g_lstMessageHandleThreads.begin();
|
||||
while( iMT!=g_lstMessageHandleThreads.end() ){
|
||||
(*iMT)->Terminate();
|
||||
delete (*iMT);
|
||||
|
||||
iMT = g_lstMessageHandleThreads.erase( iMT );
|
||||
}
|
||||
|
||||
if( g_pIOCmpltThread ){
|
||||
g_pIOCmpltThread->Terminate();
|
||||
delete g_pIOCmpltThread;
|
||||
g_pIOCmpltThread = NULL;
|
||||
}
|
||||
|
||||
FreeDB();
|
||||
|
||||
if( g_pDataBuffers ){
|
||||
delete g_pDataBuffers;
|
||||
g_pDataBuffers = NULL;
|
||||
}
|
||||
|
||||
if( g_pResponses ){
|
||||
delete g_pResponses;
|
||||
g_pResponses = NULL;
|
||||
}
|
||||
|
||||
DebugModuleClose();
|
||||
|
||||
WSACleanup( );
|
||||
|
||||
DebugPrint( "System unloaded!" );
|
||||
|
||||
if( g_hEvServiceThread ){
|
||||
SetEvent( g_hEvServiceThread );
|
||||
}
|
||||
|
||||
_tprintf(TEXT("Composer Service stopped.\n"));
|
||||
}
|
||||
/*
|
||||
#ifndef _DEBUG
|
||||
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址
|
||||
#endif
|
||||
*/
|
||||
DWORD WINAPI DBMain(void* pParam)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
if( !ServiceInit() ){
|
||||
// return 1;
|
||||
}
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
|
||||
DWORD timeCount = st.wHour * 60 * 60 + st.wMinute * 60 + st.wSecond;
|
||||
// timeCount = 0; //test
|
||||
|
||||
UINT uTimer = SetTimer( NULL, 0, 1000, NULL );
|
||||
|
||||
while( GetMessage(&msg, NULL, 0, 0) && msg.message!=WM_CLOSE ){
|
||||
if( msg.message==WM_TIMER && msg.wParam==uTimer ){
|
||||
if( g_pIOCmpltThread ){
|
||||
g_pIOCmpltThread->OnTimer();
|
||||
}
|
||||
|
||||
if( g_pDataBuffers ){
|
||||
g_pDataBuffers->OnTimer();
|
||||
}
|
||||
|
||||
if( g_pResponses ){
|
||||
g_pResponses->OnTimer();
|
||||
}
|
||||
|
||||
if( ++timeCount>=86400 ){ //00:00:00
|
||||
// if( ++timeCount>=600 ){ //test 10 minutes
|
||||
// timeCount = 0; //test
|
||||
GetLocalTime(&st);
|
||||
timeCount = st.wHour * 60 * 60 + st.wMinute * 60 + st.wSecond;
|
||||
|
||||
if( st.wHour==0 ){
|
||||
// _beginthread( OnTimerFunc, 0, NULL );
|
||||
CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)OnTimerFunc, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( timeCount & 0x1FF )==0 ){ //512s~9m
|
||||
f_DB_CleanVipLog();
|
||||
}
|
||||
|
||||
if( ( timeCount & 0xFFF )==0 ){ //4095s~68m~1h 获取测试版本信息
|
||||
ReadConfigParams();
|
||||
}
|
||||
|
||||
if( ( timeCount & 0x1FFF )==0 ){ //8191s~136m~2h 获取发布版本信息
|
||||
GetClientUpdateVersion();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try{
|
||||
TranslateMessage (&msg);
|
||||
DispatchMessage (&msg);
|
||||
}catch (...){
|
||||
_tprintf(TEXT("!!!!!!Unexpected exception in WMain()!!!!!!\n"));
|
||||
}
|
||||
}
|
||||
|
||||
KillTimer( NULL, uTimer );
|
||||
|
||||
IF_DEBUG_SYSMANAGER(DebugPrint("%X:In %s Line %d WMain ExitThread!\n",
|
||||
TRACE_NUMBER(e_Trace_SysManager,e_Trace_Normal),
|
||||
__FILE__,__LINE__))
|
||||
|
||||
ServiceDeInit();
|
||||
|
||||
_tprintf(TEXT("WMain() ExitThread!\n"));
|
||||
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef ServiceInitH
|
||||
#define ServiceInitH
|
||||
|
||||
#ifdef _SERVICEINIT_CPP
|
||||
HWND g_hWnd = NULL;
|
||||
HANDLE g_hEvServiceThread = NULL;
|
||||
#else
|
||||
extern HWND g_hWnd;
|
||||
extern HANDLE g_hEvServiceThread;
|
||||
#endif
|
||||
|
||||
bool ServiceInit();
|
||||
void ServiceDeInit();
|
||||
|
||||
DWORD WINAPI DBMain(void* pParam);
|
||||
|
||||
#endif //_SERVICEINIT_H
|
||||
@@ -0,0 +1,566 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "ServiceThread.h"
|
||||
#include "DBInterface.h"
|
||||
#include "MessageThread.h"
|
||||
#include "DataBuffers.h"
|
||||
#include "ResponseManager.h"
|
||||
#include "EpollThread.h"
|
||||
#include "INIParser.h"
|
||||
|
||||
extern int g_eDebug;
|
||||
extern int g_iChkStyle;
|
||||
extern MHTHREADLIST g_lstMessageHandleThreads;
|
||||
extern CSema* g_pSemaStop;
|
||||
|
||||
int g_iSignal = 0;
|
||||
CSema* g_pSemaService = NULL;
|
||||
CSema* g_pSemaClientCheck = NULL;
|
||||
CSema* g_pSemaTimer = NULL;
|
||||
|
||||
CUDPMessageReceiveThread * g_pMessageReceiveThread = NULL;
|
||||
EpollThread* g_pEpollThread = NULL;
|
||||
CDataBufferManager* g_pDataBuffers = NULL;
|
||||
CResponseManager* g_pResponses = NULL;
|
||||
int g_aStyleRecomList[MAX_STYLE_NUM+1];
|
||||
TQNAITEM g_lstCommonQnA[200];
|
||||
TNOTICEITEM g_lstPublicNotice[MAX_NOTICE_NUM];
|
||||
int g_nCommonQnANum = 0, g_nPublicNoticeNum = 0;
|
||||
|
||||
TCLIENTVERSION* g_pVersionClient = NULL;
|
||||
TTESTVERSION* g_pVersionClientTest = NULL;
|
||||
|
||||
int g_nClientTypeNum = 0,
|
||||
g_nClientTestNum = 0;
|
||||
HANDLE g_hEvClientCheck = NULL;
|
||||
char g_strStyleFileDir[256] = "";
|
||||
char g_strWebFileDir[256] = "";
|
||||
char g_strMusicFileDir[256] = "";
|
||||
char g_strMusicLocation[8] = "";
|
||||
char g_strServiceDir[256] = "";
|
||||
|
||||
void SignalHandler(int signo)
|
||||
{
|
||||
if(signo==SIGTERM || signo==SIGINT || signo==SIGUSR1){
|
||||
DebugPrint("Terminate by signal: %d", signo);
|
||||
|
||||
if(signo==SIGUSR1)
|
||||
g_iSignal = signo;
|
||||
|
||||
if(g_pSemaStop)
|
||||
g_pSemaStop->ActV();
|
||||
}
|
||||
else if(signo==SIGALRM){
|
||||
if(g_pSemaTimer)
|
||||
g_pSemaTimer->ActV();
|
||||
}
|
||||
}
|
||||
|
||||
void CreateLog()
|
||||
{
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
time(&t);
|
||||
tm = localtime(&t);
|
||||
|
||||
char szBufPath[256] = "";
|
||||
|
||||
sprintf( szBufPath, "%s/log/", g_strServiceDir );
|
||||
|
||||
// DebugPrint(szBufPath);
|
||||
|
||||
if( chdir(szBufPath) == -1)
|
||||
mkdir(szBufPath, S_IRWXU|S_IRWXG);
|
||||
|
||||
sprintf( szBufPath, "%s%04d-%02d-%02d.log", szBufPath, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
|
||||
|
||||
DebugModuleClose();
|
||||
|
||||
int iDebug = g_eDebug>0 ? g_eDebug : 1;
|
||||
|
||||
DebugModuleInitialize( 0xFFFF, (EDPrintDest)iDebug, szBufPath );
|
||||
}
|
||||
|
||||
#define INI_FILE_NAME "DBService.ini"
|
||||
#define STR_TESTVERSION_SECTION "TEST_VERSIONS"
|
||||
#define STR_TESTVERSION "VERSIONS_STRING"
|
||||
#ifdef _WIN32
|
||||
#define stat _stat
|
||||
#endif
|
||||
|
||||
time_t g_ftIniModify = 0;
|
||||
void ReadConfigParams()
|
||||
{
|
||||
char szFileName[260] = "";
|
||||
sprintf( szFileName, "%s/%s", g_strServiceDir, INI_FILE_NAME );
|
||||
|
||||
struct stat stFile;
|
||||
if( stat( szFileName, &stFile )!=0 ){
|
||||
DebugPrint( "get ini file stat error: %d", errno );
|
||||
return;
|
||||
}
|
||||
|
||||
if( g_ftIniModify!=stFile.st_mtime ){
|
||||
if(g_pSemaClientCheck->ActP())
|
||||
return;
|
||||
|
||||
//printf( "retrive config.\n" );
|
||||
TTESTVERSION aVersion[10];
|
||||
int num = 0;
|
||||
|
||||
INIParser parser;
|
||||
parser.ReadINI(szFileName);
|
||||
|
||||
string szLine = parser.GetValue(STR_TESTVERSION_SECTION, STR_TESTVERSION);
|
||||
if( !szLine.empty() ){
|
||||
char szBuf[512] = "";
|
||||
strcpy(szBuf, szLine.c_str());
|
||||
|
||||
char *tokenPtr=strtok( szBuf, "|" );
|
||||
for( ; tokenPtr!=NULL; num++ ){
|
||||
int iInner, iMaj, iMin, iMod, iBuil;
|
||||
sscanf( tokenPtr, "%d,%d.%d.%d", &iInner, &iMaj, &iMin, &iMod );//, &iBuil );
|
||||
|
||||
aVersion[num].iClientType = iInner;
|
||||
aVersion[num].version.majorVersion = iMaj;
|
||||
aVersion[num].version.minorVersion = iMin;
|
||||
aVersion[num].version.modifyVersion = iMod;
|
||||
// aVersion[num].version.buildVersion = iBuil;
|
||||
|
||||
tokenPtr = strtok( NULL, "|" );
|
||||
}
|
||||
}
|
||||
|
||||
parser.Clear();
|
||||
|
||||
if( g_nClientTestNum>0 && g_nClientTestNum!=num ){
|
||||
delete[] g_pVersionClientTest;
|
||||
g_pVersionClientTest = NULL;
|
||||
}
|
||||
|
||||
g_nClientTestNum = num;
|
||||
|
||||
if( num>0 ){
|
||||
if( !g_pVersionClientTest ){
|
||||
g_pVersionClientTest = new TTESTVERSION[num];
|
||||
}
|
||||
|
||||
for( int i=0; i<num; i++ ){
|
||||
TTESTVERSION* pVersion = &(g_pVersionClientTest[i]);
|
||||
memcpy( pVersion, &aVersion[i], sizeof(TTESTVERSION) );
|
||||
|
||||
DebugPrint( "测试版本: %d.%d.%d\t软件内部编号: %d",
|
||||
pVersion->version.majorVersion, pVersion->version.minorVersion,
|
||||
pVersion->version.modifyVersion, //pVersion->version.buildVersion, //不设置构建版本
|
||||
pVersion->iClientType );
|
||||
}
|
||||
}
|
||||
else{
|
||||
DebugPrint( "No test version." );
|
||||
}
|
||||
|
||||
g_pSemaClientCheck->ActV();
|
||||
// SetEvent( g_hEvClientCheck );
|
||||
|
||||
g_ftIniModify = stFile.st_mtime;
|
||||
}
|
||||
else{
|
||||
DebugPrint( "No config update." );
|
||||
}
|
||||
}
|
||||
|
||||
void GetStyleRecomList()
|
||||
{
|
||||
int tempList[MAX_STYLE_NUM+1];
|
||||
memset( tempList, 0, sizeof(int)*(MAX_STYLE_NUM+1) );
|
||||
int num = MAX_STYLE_NUM;
|
||||
int ret = f_DB_GetRecomStyleIDs( &num, tempList );
|
||||
|
||||
if( ret==0 ){
|
||||
tempList[MAX_STYLE_NUM] = num;
|
||||
memcpy( g_aStyleRecomList, tempList, sizeof(int)*(MAX_STYLE_NUM+1) );
|
||||
|
||||
DebugPrint( "Recommand style num : %d", num );
|
||||
}
|
||||
else{
|
||||
DebugPrint( "DB_GetRecomStyleIDs return %d", ret );
|
||||
}
|
||||
}
|
||||
|
||||
void GetCommonQnAList()
|
||||
{
|
||||
// int dtUpdate = 0;
|
||||
// for( int i=0; i<g_nCommonQnANum; i++ ){
|
||||
// if( dtUpdate<g_lstCommonQnA[i].dtUpdate ){
|
||||
// dtUpdate = g_lstCommonQnA[i].dtUpdate;
|
||||
// }
|
||||
// }
|
||||
|
||||
// g_nCommonQnANum = f_DB_GetCommonQnA( dtUpdate, g_nCommonQnANum, g_lstCommonQnA );
|
||||
g_nCommonQnANum = f_DB_GetCommonQnA( 0, g_nCommonQnANum, g_lstCommonQnA );
|
||||
|
||||
DebugPrint( "Common QnA num : %d", g_nCommonQnANum );
|
||||
}
|
||||
|
||||
void GetPublicNoticeList()
|
||||
{
|
||||
g_nPublicNoticeNum = f_DB_GetNotice( MAX_NOTICE_NUM, g_lstPublicNotice, 0 );
|
||||
|
||||
DebugPrint( "Public notice num : %d", g_nPublicNoticeNum );
|
||||
}
|
||||
|
||||
void GetClientUpdateVersion()
|
||||
{
|
||||
if( !g_pSemaClientCheck || g_pSemaClientCheck->ActP() ){
|
||||
return;
|
||||
}
|
||||
|
||||
int nOldTypeNum = g_nClientTypeNum;
|
||||
g_nClientTypeNum = f_DB_GetClientTypeNumber();
|
||||
|
||||
TCLIENTVERSION * pClients = NULL;
|
||||
if( g_nClientTypeNum>0 ){ //有可用客户端
|
||||
pClients = new TCLIENTVERSION[g_nClientTypeNum];
|
||||
if( f_DB_GetClientVersion( pClients, g_nClientTypeNum )<0 ){ //获取客户端信息
|
||||
delete[] pClients;
|
||||
pClients = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool bChange = true;
|
||||
if( g_nClientTypeNum<0 ){
|
||||
DebugPrint( "获取最新客户端类型数失败!" );
|
||||
g_nClientTypeNum = nOldTypeNum; //不改变原客户端信息
|
||||
bChange = false;
|
||||
}
|
||||
else if(g_nClientTypeNum>0 && !pClients){
|
||||
DebugPrint( "获取最新客户端版本信息失败!" );
|
||||
g_nClientTypeNum = nOldTypeNum; //不改变原客户端信息
|
||||
bChange = false;
|
||||
}
|
||||
else if( g_nClientTypeNum==nOldTypeNum ){ //数量相同则比较是否有改变
|
||||
bChange = false;
|
||||
for( int i=0; i<g_nClientTypeNum; i++ ){
|
||||
TCLIENTVERSION* pOldVersion = &(g_pVersionClient[i]);
|
||||
TCLIENTVERSION* pNewVersion = &(pClients[i]);
|
||||
if(memcmp(pOldVersion, pNewVersion, sizeof(TCLIENTVERSION))){
|
||||
bChange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bChange){ //有变化
|
||||
if(g_pVersionClient) //清理原内存
|
||||
delete[] g_pVersionClient;
|
||||
|
||||
g_pVersionClient = pClients;
|
||||
|
||||
for( int i=0; i<g_nClientTypeNum; i++ ){ //打印信息
|
||||
TCLIENTVERSION* pVersion = &(g_pVersionClient[i]);
|
||||
|
||||
DebugPrint( "软件内部编号: %d\n\t最新客户端版本: %d.%d.%d.%04d\n\t发布时间: %d-%d-%d",
|
||||
pVersion->iClientType,
|
||||
pVersion->swInfo.version.majorVersion, pVersion->swInfo.version.minorVersion,
|
||||
pVersion->swInfo.version.modifyVersion, pVersion->swInfo.version.buildVersion,
|
||||
pVersion->swInfo.tIssueDate>>16, (pVersion->swInfo.tIssueDate&0xFF00)>>8, (pVersion->swInfo.tIssueDate&0xFF));
|
||||
|
||||
}
|
||||
}
|
||||
else if(pClients){ //无变化清理内存
|
||||
delete[] pClients;
|
||||
pClients = NULL;
|
||||
}
|
||||
|
||||
g_pSemaClientCheck->ActV();
|
||||
}
|
||||
|
||||
bool ServiceInit()
|
||||
{
|
||||
g_pSemaService = new CSema(NULL, 0);
|
||||
g_pSemaClientCheck = new CSema(NULL, 1);
|
||||
g_pSemaTimer = new CSema(NULL, 0);
|
||||
|
||||
CreateLog();
|
||||
//DebugPrint("DebugModuleInitialize success!\n");
|
||||
|
||||
//载入数据库访问模块
|
||||
if( !LoadDB() ){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
f_DB_GetPath( g_strStyleFileDir, g_strWebFileDir, g_strMusicFileDir );
|
||||
DebugPrint( "Style_dir: %s\n\tWeb_dir: %s\n\tMusic_dir: %s", g_strStyleFileDir, g_strWebFileDir, g_strMusicFileDir );
|
||||
if( strlen(g_strMusicFileDir)>0 ){
|
||||
char* pos = strstr( g_strMusicFileDir, "File" )+4;
|
||||
if( pos[0]!='/' && pos[0]!='\\' ){
|
||||
int num;
|
||||
sscanf( pos, "%d", &num );
|
||||
sprintf( g_strMusicLocation, "%d", num );
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//修改风格信息专用
|
||||
if( g_iChkStyle>0 ){
|
||||
// UpdateStyleInfo();
|
||||
// ModifyStyleDesc();
|
||||
return FALSE;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
GetClientUpdateVersion();
|
||||
memset( g_aStyleRecomList, 0, sizeof(int)*(MAX_STYLE_NUM+1) );
|
||||
GetStyleRecomList();
|
||||
|
||||
ReadConfigParams();
|
||||
|
||||
GetCommonQnAList();
|
||||
GetPublicNoticeList();
|
||||
|
||||
//创建数据接收
|
||||
g_pDataBuffers = new CDataBufferManager;
|
||||
//创建消息响应管理
|
||||
g_pResponses = new CResponseManager;
|
||||
|
||||
//生成UDP消息接收线程
|
||||
CUDPSocket * pSocket = new CUDPSocket( LISTEN_PORT );
|
||||
if( pSocket && pSocket->IsOpen() ){
|
||||
g_pMessageReceiveThread = new CUDPMessageReceiveThread( 3000, pSocket );
|
||||
g_pMessageReceiveThread->Resume();
|
||||
|
||||
//生成消息处理线程池
|
||||
for( int i=0; i<20; i++ ){
|
||||
CMessageHandleThread* pThread = new CMessageHandleThread( 3000, pSocket );
|
||||
g_lstMessageHandleThreads.push_back( pThread );
|
||||
}
|
||||
}
|
||||
|
||||
//生成epoll线程
|
||||
g_pEpollThread = new EpollThread();
|
||||
g_pEpollThread->Resume();
|
||||
|
||||
printf("Composer Service is running...\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServiceDeInit()
|
||||
{
|
||||
printf("Composer Service is stopping...\n");
|
||||
|
||||
// if( g_hEvClientCheck ){
|
||||
// CloseHandle( g_hEvClientCheck );
|
||||
// }
|
||||
if( g_pSemaClientCheck ){
|
||||
delete g_pSemaClientCheck;
|
||||
g_pSemaClientCheck = NULL;
|
||||
}
|
||||
|
||||
if( g_pSemaTimer ){
|
||||
delete g_pSemaTimer;
|
||||
g_pSemaTimer = NULL;
|
||||
}
|
||||
|
||||
if( g_pVersionClient ){
|
||||
delete[] g_pVersionClient;
|
||||
g_pVersionClient = NULL;
|
||||
}
|
||||
|
||||
if( g_pMessageReceiveThread ){
|
||||
g_pMessageReceiveThread->Terminate();
|
||||
delete g_pMessageReceiveThread;
|
||||
g_pMessageReceiveThread = NULL;
|
||||
}
|
||||
|
||||
MHTHREADLIST::iterator iMT = g_lstMessageHandleThreads.begin();
|
||||
while( iMT!=g_lstMessageHandleThreads.end() ){
|
||||
(*iMT)->Terminate();
|
||||
// (*iMT)->Resume();
|
||||
delete (*iMT);
|
||||
|
||||
iMT = g_lstMessageHandleThreads.erase( iMT );
|
||||
}
|
||||
|
||||
if( g_pEpollThread ){
|
||||
g_pEpollThread->Terminate();
|
||||
}
|
||||
|
||||
FreeDB();
|
||||
|
||||
if( g_pDataBuffers ){
|
||||
delete g_pDataBuffers;
|
||||
g_pDataBuffers = NULL;
|
||||
}
|
||||
|
||||
if( g_pResponses ){
|
||||
delete g_pResponses;
|
||||
g_pResponses = NULL;
|
||||
}
|
||||
|
||||
if( g_pEpollThread ){
|
||||
delete g_pEpollThread;
|
||||
g_pEpollThread = NULL;
|
||||
}
|
||||
|
||||
DebugModuleClose();
|
||||
|
||||
printf( "System unloaded!\n" );
|
||||
|
||||
if(g_pSemaService)
|
||||
g_pSemaService->ActV();
|
||||
|
||||
printf("Composer Service stopped.\n");
|
||||
}
|
||||
|
||||
// void CheckProCount()
|
||||
// {
|
||||
// //////////////////////////////////////////////////////
|
||||
// // 统计 PC pro 函数
|
||||
// #include "MessageHandle.h"
|
||||
// int n826(0), nOth(0);
|
||||
// GetProCount(n826, nOth);
|
||||
|
||||
// DebugPrint("PC pro使用人数 826 : other = %d : %d", n826, nOth);
|
||||
// //////////////////////////////////////////////////////
|
||||
// }
|
||||
|
||||
void* OneDaySchedule(void* arg)
|
||||
{
|
||||
// CheckProCount();
|
||||
|
||||
CreateLog();
|
||||
GetStyleRecomList();
|
||||
GetCommonQnAList();
|
||||
CheckMemoryUsage();
|
||||
|
||||
DebugPrint( "OneDaySchedule exit." );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int SetTimer(int sec)
|
||||
{
|
||||
itimerval value;
|
||||
value.it_value.tv_sec = sec;
|
||||
value.it_value.tv_usec = 0;
|
||||
value.it_interval = value.it_value;
|
||||
|
||||
return setitimer(ITIMER_REAL, &value, NULL);
|
||||
}
|
||||
|
||||
int GetTimeCount()
|
||||
{
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
time(&t);
|
||||
tm = localtime(&t);
|
||||
|
||||
return tm->tm_hour * 60 * 60 + tm->tm_min * 60 + tm->tm_sec;
|
||||
}
|
||||
|
||||
CServiceThread::CServiceThread():CThread(3000)
|
||||
{
|
||||
// getcwd(g_strServiceDir, 256);
|
||||
if(readlink("/proc/self/exe", g_strServiceDir, 256)>0){
|
||||
char* p = strrchr(g_strServiceDir,'/');
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceThread::Terminate()
|
||||
{
|
||||
CThread::Terminate();
|
||||
|
||||
if( g_pSemaTimer )
|
||||
g_pSemaTimer->ActV();
|
||||
}
|
||||
|
||||
void CServiceThread::Main()
|
||||
{
|
||||
DWORD timeCount = 0;
|
||||
|
||||
if( ServiceInit() ){
|
||||
timeCount = GetTimeCount();
|
||||
|
||||
/* 设置信号的处理方式 */
|
||||
signal(SIGALRM, SignalHandler);
|
||||
signal(SIGTERM, SignalHandler);
|
||||
signal(SIGINT, SignalHandler);
|
||||
signal(SIGUSR1, SignalHandler);
|
||||
|
||||
/* 以系统真实的时间来计算,将送出SIGALRM信号 */
|
||||
if (SetTimer(1) < 0){
|
||||
/* 函数调用返回错误 */
|
||||
DebugPrint("Setitimer Failed : %s", strerror(errno));
|
||||
Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
while(!m_bExit){
|
||||
g_pSemaTimer->ActP();
|
||||
|
||||
// if( g_pIOCmpltThread ){
|
||||
// g_pIOCmpltThread->OnTimer();
|
||||
// }
|
||||
|
||||
if( g_pDataBuffers ){
|
||||
g_pDataBuffers->OnTimer();
|
||||
}
|
||||
|
||||
if( g_pResponses ){
|
||||
g_pResponses->OnTimer();
|
||||
}
|
||||
|
||||
if( ++timeCount>=86400 ){ //00:00:00
|
||||
// if( ++timeCount>=15 ){ //test 10 minutes
|
||||
// timeCount = 0; //test
|
||||
timeCount = GetTimeCount();
|
||||
|
||||
if( timeCount<3600 ){
|
||||
#ifdef _WIN32
|
||||
CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)OnTimerFunc, 0, 0, 0 );
|
||||
#else
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create( &tid, &attr, OneDaySchedule, NULL);
|
||||
pthread_attr_destroy (&attr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if( ( timeCount & 0x1FF )==0 ){ //0x1FF 512s~9m 定时清除VIP登录记录(10分钟内最多3个设备同时登录)
|
||||
f_DB_CleanVipLog();
|
||||
}
|
||||
|
||||
if( timeCount>0 && ( timeCount & 0xFFF )==0 //0xFFF 4095s~68m~1h 获取测试版本信息等
|
||||
&& timeCount < 86000 ){ //23:53:35秒的检测跳过
|
||||
ReadConfigParams();
|
||||
GetClientUpdateVersion();
|
||||
GetPublicNoticeList();
|
||||
}
|
||||
|
||||
// if( ( timeCount & 0x1FFF )==0 ){ //0x1FFF 8191s~136m~2h 获取发布版本信息
|
||||
// GetClientUpdateVersion();
|
||||
// GetPublicNoticeList();
|
||||
// }
|
||||
}
|
||||
|
||||
SetTimer(0);
|
||||
|
||||
// CheckProCount();
|
||||
|
||||
ServiceDeInit();
|
||||
|
||||
DebugPrint("Service main thread exited.");
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef ServiceThreadH
|
||||
#define ServiceThreadH
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
void SignalHandler(int);
|
||||
|
||||
// CServiceThread
|
||||
//
|
||||
class CServiceThread : public CThread
|
||||
{
|
||||
private:
|
||||
public:
|
||||
CServiceThread();
|
||||
virtual void Terminate() ;
|
||||
virtual void Main();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,264 @@
|
||||
#define _DEBUG_CPP_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#endif
|
||||
|
||||
//#include "object.h"
|
||||
#include "Socket.h"
|
||||
#include "debug.h"
|
||||
|
||||
EDPrintDest g_nDest;//表示打印的目的地
|
||||
CTCPSocket * g_pNetChannel = NULL;
|
||||
FILE * g_pFileChannel = NULL;
|
||||
|
||||
//using namespace std;
|
||||
/*******************************************************
|
||||
int DebugPrint(const char * fmt, ...)
|
||||
功能描述:
|
||||
提供类似于printf的调试打印语句
|
||||
********************************************************/
|
||||
int DebugPrint(const char * fmt, ...)
|
||||
{
|
||||
char sDebug[MAX_DEBUG_PRINT];
|
||||
sDebug[0] = '\0';
|
||||
/*
|
||||
int nLen=strlen(sDebug);
|
||||
sDebug[nLen]='@';
|
||||
sDebug[nLen+1]='\0';
|
||||
*/
|
||||
if( g_nDest!=e_ToNet ){
|
||||
time_t now;
|
||||
time(&now);
|
||||
strftime(sDebug, sizeof(sDebug), "[%H:%M:%S] ",localtime(&now));
|
||||
}
|
||||
|
||||
va_list vaParams;
|
||||
va_start(vaParams,fmt);
|
||||
|
||||
vsprintf(sDebug+strlen(sDebug),fmt,vaParams);
|
||||
|
||||
if( g_nDest==e_ToNet ){
|
||||
int nLen=strlen(sDebug);
|
||||
sDebug[nLen]='@';
|
||||
sDebug[nLen+1]='\0';
|
||||
}
|
||||
|
||||
switch (g_nDest){
|
||||
case e_ToFile:
|
||||
{
|
||||
if( g_pFileChannel==NULL )
|
||||
return 0;
|
||||
|
||||
fprintf(g_pFileChannel,"%s\n",sDebug);
|
||||
fflush(g_pFileChannel);
|
||||
break;
|
||||
}
|
||||
case e_ToNet:
|
||||
{
|
||||
if( g_pNetChannel==NULL || !g_pNetChannel->IsOpen() )
|
||||
return 0;
|
||||
|
||||
g_pNetChannel->Send( sDebug, strlen(sDebug));
|
||||
break;
|
||||
}
|
||||
case e_ToScreen:
|
||||
{
|
||||
printf( "%s\n", sDebug );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OutputDebugString( sDebug );
|
||||
#else
|
||||
printf( "%s\n", sDebug );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*******************************************************
|
||||
void DebugModuleInitialize(int nDebug,EDPrintDest nDest,char *sHost)
|
||||
参数说明:
|
||||
int nDebug
|
||||
产品的名称
|
||||
EDPrintDest nDest
|
||||
使用什么方式打印
|
||||
char *sHost
|
||||
使用网络打印时用的主机地址
|
||||
|
||||
功能描述:
|
||||
初始化调试模块
|
||||
********************************************************/
|
||||
void DebugModuleInitialize(int nDebug,EDPrintDest nDest,char *sHost)
|
||||
{
|
||||
if( nDebug==0 ) return;
|
||||
g_nDebugFlag = nDebug;
|
||||
g_nDest = nDest;
|
||||
|
||||
switch (g_nDest){
|
||||
case e_ToFile:
|
||||
{
|
||||
g_pFileChannel = fopen( sHost, "a+" );
|
||||
break;
|
||||
}
|
||||
case e_ToNet:
|
||||
{
|
||||
g_pNetChannel = new CTCPSocket( DEBUG_HOST, DEBUG_TCPPORT );
|
||||
if( g_pNetChannel && !g_pNetChannel->IsOpen() ){
|
||||
delete g_pNetChannel;
|
||||
g_pNetChannel = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************
|
||||
void DebugModuleClose()
|
||||
功能描述:
|
||||
停止使用调试模块
|
||||
********************************************************/
|
||||
void DebugModuleClose()
|
||||
{
|
||||
switch (g_nDest){
|
||||
case e_ToFile:
|
||||
{
|
||||
if( g_pFileChannel )
|
||||
fclose( g_pFileChannel );
|
||||
g_pFileChannel = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
case e_ToNet:
|
||||
{
|
||||
if( g_pNetChannel )
|
||||
delete g_pNetChannel;
|
||||
g_pNetChannel = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DllDebugModuleInitialize(int nDebug,EDPrintDest nDest,void* pChannel)
|
||||
{
|
||||
if( nDebug==0 ) return;
|
||||
g_nDebugFlag = nDebug;
|
||||
g_nDest = nDest;
|
||||
switch (g_nDest){
|
||||
case e_ToFile:
|
||||
{
|
||||
g_pFileChannel = (FILE*)pChannel;
|
||||
break;
|
||||
}
|
||||
case e_ToNet:
|
||||
{
|
||||
g_pNetChannel = (CTCPSocket*)pChannel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DllDebugModuleClose()
|
||||
{
|
||||
g_nDest = e_NoDest;
|
||||
g_pFileChannel = NULL;
|
||||
g_pNetChannel = NULL;
|
||||
}
|
||||
|
||||
void GetDebugParams(int &nDebug,EDPrintDest &nDest,void **pChan)
|
||||
{
|
||||
nDebug = g_nDebugFlag;
|
||||
nDest = g_nDest;
|
||||
switch (g_nDest){
|
||||
case e_ToFile:
|
||||
*pChan = (void*)g_pFileChannel;
|
||||
break;
|
||||
|
||||
case e_ToNet:
|
||||
*pChan = (void*)g_pNetChannel;
|
||||
break;
|
||||
|
||||
case e_ToScreen:
|
||||
case e_ToDebug:
|
||||
*pChan = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
long GetMemoryUsage()
|
||||
{
|
||||
long mem = 0L;
|
||||
FILE* fp = fopen( "/proc/self/statm", "r" );
|
||||
if( fp != NULL ){
|
||||
long rss;
|
||||
if ( fscanf( fp, "%*s%ld", &rss ) == 1 )
|
||||
mem = rss << 2;
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
#include <signal.h>
|
||||
#include <thread.h>
|
||||
#include <malloc.h>
|
||||
extern char g_strServiceDir[256];
|
||||
int u_nCurrMemUsedMax(0), u_nCurrMemUsedMin(0);
|
||||
char u_szMemLog[256] = "";
|
||||
CSema u_smMemLog("smMemLog",1);
|
||||
|
||||
void CheckMemoryUsage(int iParam)
|
||||
{
|
||||
CMutexLock lockProcess( &u_smMemLog );
|
||||
|
||||
int mem = (int)GetMemoryUsage();
|
||||
if(mem>u_nCurrMemUsedMax){
|
||||
if(u_nCurrMemUsedMax>u_nCurrMemUsedMin){ //记录波峰波谷
|
||||
if(strlen(u_szMemLog)==0)
|
||||
sprintf( u_szMemLog, "%s/mem.log", g_strServiceDir );
|
||||
|
||||
char sTime[32] = "";
|
||||
time_t now;
|
||||
time(&now);
|
||||
strftime(sTime, 32, "%Y-%m-%d %H:%M:%S",localtime(&now));
|
||||
|
||||
FILE* fp = fopen( u_szMemLog, "a+" );
|
||||
if(fp){
|
||||
fprintf(fp, "[%s] %8d %8d\n", sTime, u_nCurrMemUsedMin, u_nCurrMemUsedMax);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
u_nCurrMemUsedMax = u_nCurrMemUsedMin = mem;
|
||||
|
||||
DebugPrint("!!!!! Memory used: %d, msg: 0x%X", mem, iParam);
|
||||
|
||||
if(mem>131072 && !malloc_trim(0)){
|
||||
DebugPrint("!!!!! Memory exceeded: %d", mem);
|
||||
raise(SIGUSR1);
|
||||
}
|
||||
}
|
||||
else if(mem<u_nCurrMemUsedMin){
|
||||
u_nCurrMemUsedMin = mem;
|
||||
DebugPrint("!!!!! Memory used: %d, msg: 0x%X", mem, iParam);
|
||||
}
|
||||
else if(iParam==0){
|
||||
DebugPrint("!!!!! Memory used: %d, (%d - %d)", mem, u_nCurrMemUsedMin, u_nCurrMemUsedMax);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
#ifndef DebugH
|
||||
#define DebugH
|
||||
|
||||
#ifdef _DEBUG_CPP_
|
||||
int g_nDebugFlag=0xFFFF;
|
||||
#else
|
||||
extern int g_nDebugFlag;
|
||||
#endif
|
||||
|
||||
enum EDPrintDest{
|
||||
e_NoDest,
|
||||
e_ToFile,
|
||||
e_ToNet,
|
||||
e_ToScreen,
|
||||
e_ToDebug
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DEBUG_FILE "ComposeServiceLog.txt"
|
||||
#define DEBUG_HOST "127.0.0.1"
|
||||
#define DEBUG_TCPPORT 2510
|
||||
#define MAX_DEBUG_PRINT 10240
|
||||
|
||||
/*Debug代码*/
|
||||
int DebugPrint(const char *fmt,...);
|
||||
void DebugModuleInitialize(int nDebug,EDPrintDest nDest,char *sHost=DEBUG_HOST);
|
||||
void DebugModuleClose();
|
||||
void GetDebugParams( int &nDebug, EDPrintDest &nDest, void **pChan );
|
||||
long GetMemoryUsage();
|
||||
void CheckMemoryUsage(int iParam=0);
|
||||
|
||||
#ifdef _WIN32
|
||||
void DllDebugModuleClose();
|
||||
void __declspec(dllexport) DllDebugModuleInitialize(int nDebug,EDPrintDest nDest,void* pChannel);
|
||||
typedef void (*PFDLLDEBUGINITIALIZE)(int nDebug,EDPrintDest nDest,void* pChannel);
|
||||
#endif
|
||||
|
||||
/*条件判断语句*/
|
||||
#define DEBUG_COMMON 0x0001
|
||||
#define DEBUG_CLIENTAPP 0x0002
|
||||
#define DEBUG_SYSMANAGER 0x0004
|
||||
#define DEBUG_CLIENTMANAGER 0x0008
|
||||
#define DEBUG_NODEMANAGER 0x0010
|
||||
#define DEBUG_CONFMANAGER 0x0020
|
||||
#define DEBUG_CONFCONTROL 0x0080
|
||||
#define DEBUG_GATEKEEPER 0x0100
|
||||
#define DEBUG_MCUSTACK 0x0200
|
||||
#define DEBUG_NETMANAGER 0x0400
|
||||
#define DEBUG_CONNECTION 0x0040
|
||||
|
||||
#define IF_DEBUGOUT(f) if (g_nDebugFlag & (f))
|
||||
#define IF_DEBUG_COMMON(A) IF_DEBUGOUT(DEBUG_COMMON) {A;};
|
||||
#define IF_DEBUG_CLIENTAPP(A) IF_DEBUGOUT(DEBUG_CLIENTAPP) {A;};
|
||||
#define IF_DEBUG_SYSMANAGER(A) IF_DEBUGOUT(DEBUG_SYSMANAGER) {A;};
|
||||
#define IF_DEBUG_CLIENTMANAGER(A) IF_DEBUGOUT()DEBUG_CLIENTMANAGER {A;};
|
||||
#define IF_DEBUG_NODEMANAGER(A) IF_DEBUGOUT(DEBUG_NODEMANAGER) {A;};
|
||||
#define IF_DEBUG_CONFMANAGER(A) IF_DEBUGOUT(DEBUG_CONFMANAGER) {A;};
|
||||
#define IF_DEBUG_CONFCONTROL(A) IF_DEBUGOUT(DEBUG_CONFCONTROL) {A;};
|
||||
#define IF_DEBUG_GATEKEEPER(A) IF_DEBUGOUT(DEBUG_GATEKEEPER) {A;};
|
||||
#define IF_DEBUG_MCUSTACK(A) IF_DEBUGOUT(DEBUG_MCUSTACK) {A;};
|
||||
#define IF_DEBUG_NETMANAGER(A) IF_DEBUGOUT(DEBUG_NETMANAGER) {A;};
|
||||
#define IF_DEBUG_CONNECTION(A) IF_DEBUGOUT(DEBUG_CONNECTION) {A;}
|
||||
|
||||
/*跟踪消息的编号相关定义*/
|
||||
#define TRACE_NUMBER(nMajor,nGrade) (nMajor<<10)|(nGrade)
|
||||
#define TRACE_MAJOR(nType) (nType>>10)
|
||||
#define TRACE_GRADE(nType) (nType&0x03)
|
||||
|
||||
enum ETraceMajorType{ // 出错的模块编号
|
||||
e_Trace_Common=0x1, // 公共部分
|
||||
e_Trace_ClientApp, // 客户端程序
|
||||
e_Trace_SysManager, // 系统管理
|
||||
e_Trace_ClientManager, // 客户端管理
|
||||
e_Trace_NodeManager, // 节点管理
|
||||
e_Trace_ConfManager, // 会议管理
|
||||
e_Trace_TemplateManager, // 模板管理
|
||||
e_Trace_ConfControl, // 会议控制
|
||||
e_Trace_GateKeeper, // Gatekeeper
|
||||
e_Trace_MCUStack, // MCU协议栈
|
||||
e_Trace_NetManager // 网络管理
|
||||
};
|
||||
|
||||
enum ETraceGrade{ // 错误等级
|
||||
e_Trace_Severe, // 严重的错误可能引起异常
|
||||
e_Trace_Major, // 断言出错,值得关注
|
||||
e_Trace_Normal // 一般跟踪消息
|
||||
};
|
||||
|
||||
/*****************************************
|
||||
// Debug接口的用法示例
|
||||
//
|
||||
IF_DEBUG_COMMON(DebugPrint("%X:In %s Line %d 用来建立连接的地址非法\n",
|
||||
TRACE_NUMBER(e_Trace_Common,e_Trace_Major),
|
||||
__FILE__,__LINE__))
|
||||
*****************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // DebugH
|
||||
Reference in New Issue
Block a user