// 函数名: CSvrLink::ToLink // 编程 : 陈永华 2004-2-11 12:14:25 // 描述 : // 返回 : int // 参数 : ST_BUNIT *pBUnit int CSvrLink::ToLink(ST_BUNIT *pBUnit) { int i; int rtn; RP_LINKBEGIN rp; AP_LINKBEGIN *pap; MSGBUF *pmb; memset(&head,0,sizeof(head)); iLastReqType = 0; iLastRetCode = 0; iGRFrame = 10; // 重新开始的获取请求的帧号,注意在连接初期,必须与BCC不同,以防止不同步 linksock.Close(); rp.bu1 = 1; strncpy(rp.szBUGroupID,pBUnit->szBUGroupID,sizeof(rp.szBUGroupID)-1); rp.iDefaultAM = iDefaultAnswerMode; rp.iBUVersion = htonl(BU_VERSION); // BU的版本编码 if (linksock.ConnectTcp(pBUnit->szSvrIP,pBUnit->iSvrPort)) { for (i=0;i<5;i++) { rtn = SendMsg(MT_LINKBEGIN,sizeof(rp),&rp); if (rtn!=0) { sprintf(buf,"发送连接请求数据的时候失败,SendMsg()=%d,端口失败号为%d\n",rtn,linksock.GetLastError(NULL,0)); DEBUG_RUNTIME_MSGOUT(buf); return(rtn); } rtn = RecvMsg(pBUnit->iHBInterval); if (rtn>0 && rtn>=(int)(sizeof(MSGHEAD))) { pmb = GetRecvMsg(); if (pmb->head.msgtype==MT_LINKBEGIN && pmb->head.len>=sizeof(AP_LINKBEGIN)) { pap = (AP_LINKBEGIN *)(pmb->data); svr_hs1 = pap->bc1; // 无所谓字序的转换了,反正不会重复的,如果需要,这个参数也多数会返回给BCC的 iThisProcID = ntohl(pap->bu_number); bccBFuncNo = ntohl(pap->basefuncno); bccID = ntohl(pap->bccid); if (strlen(pap->szmsg)>0) { g_LogFile.WriteLogEx(1000,"BU%d-BCC Warning:%s",iThisProcID,pap->szmsg); } return(1); // 成功连接,可以开始处理了 } } else if (rtn!=0) { sprintf(buf,"接收连接请求数据确认的时候失败,RecvMsg()=%d,端口失败号为%d\n",rtn,linksock.GetLastError(NULL,0)); DEBUG_RUNTIME_MSGOUT(buf); return(rtn); // 接收时候失败 } } linksock.Close(); DEBUG_RUNTIME_MSGOUT("做了5次连接请求都没有应答返回!\n"); return(0); } return(-100); }
bool ReadIni(char *inifile) { TIniFile tf; CSList tmpstr; char szBuf[256]; g_LogFile.Open("bulog"); // 用程序的进程号作为各个BU日志文件存放目录 memset(&g_BUnit,0,sizeof(g_BUnit)); printf("Begin to read ini-file:%s...\n",inifile); if (!tf.Open(inifile)) { sprintf(szBuf,"不能打开配置文件<%s>\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } g_LogFile.RemoveOverdueLogFile(tf.ReadInt("COMMON","LOGOVERDUE",10)); //g_BUnit.iBUnitGourpID = tf.ReadInt("COMMON","GID",1); tf.ReadString("COMMON","GID","",g_BUnit.szBUGroupID,sizeof(g_BUnit.szBUGroupID)-1); tf.ReadString("BCC","BCCSVR","127.0.0.1:6666",szBuf,sizeof(szBuf)-1); if (!tmpstr.FillStrings(szBuf,':') || tmpstr.GetCount()<2) { sprintf(szBuf,"配置文件<%s>的配置项[BCC] BCCSVR=???? 错误! 格式为:BCCSVR=xxx.xxx.xxx.xxx:port\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } strncpy(g_BUnit.szSvrIP,tmpstr.GetAt(0),sizeof(g_BUnit.szSvrIP)-1); g_BUnit.iSvrPort = atoi(tmpstr.GetAt(1)); g_BUnit.iHBInterval = tf.ReadInt("BCC","HEARTBEAT",5000); if (g_BUnit.iHBInterval<100) g_BUnit.iHBInterval = 100; memset(szBuf,0,sizeof szBuf); // TODO : 加密机配置 char remoteip[128]={0}; int remoteport=0; tf.ReadString("ENCSVR","ip","",remoteip,sizeof(remoteip)-1); BKConfiguration::instance()->save_para("encsvr.remoteip",remoteip); remoteport = tf.ReadInt("ENCSVR","port",0); BKConfiguration::instance()->save_int_para("encsvr.remoteport",remoteport); int mainfunc = tf.ReadInt("ENCSVR","mainfunc",0); BKConfiguration::instance()->save_int_para("encsvr.mainfunc",mainfunc); int drtpno = tf.ReadInt("ENCSVR","drtpno",0); BKConfiguration::instance()->save_int_para("encsvr.drtpno",drtpno); tf.Close(); return(true); }
// 函数名: CSvrLink::SendMsg // 编程 : 陈永华 2004-2-10 21:08:11 // 描述 : 以MSG格式发送消息数据给调度中心 // 返回 : int =0:发送成功;<0:发送时候端口出现问题,端口被关闭;-100:出现设计上的错误,需要核查程序 // 参数 : short msgtype :IN 发送的消息类型 // 参数 : unsigned short msglen :IN 消息体数据长度 // 参数 : void *MSGBUF : IN 消息数据缓存 int CSvrLink::SendMsg(short msgtype, unsigned short msglen, void *MSGBUF) { int rtn; MSGHEAD *phead; char buf[MAXMSG+sizeof(MSGHEAD)]; phead = (MSGHEAD *)buf; ResetMsgHead(phead,msgtype,msglen); if (msglen>0) { memcpy(buf+sizeof(MSGHEAD),MSGBUF,msglen); } rtn = linksock.Send(buf,sizeof(MSGHEAD)+msglen); if (rtn<0) { // 发送时,端口有问题,包括被关闭 return(rtn); } else if (rtn==0) { // 不应该出现这种情况 DEBUG_RUNTIME_MSGOUT("发送消息时出现编码性错,CTcpSocket.Send不该出现==0的返回!\n"); return(-100); } return(0); }
bool ReadIni(char *inifile) { TIniFile tf; CSList tmpstr; char szBuf[256]; g_LogFile.Open("bulog"); // 用程序的进程号作为各个BU日志文件存放目录 memset(&g_BUnit,0,sizeof(g_BUnit)); printf("Begin to read ini-file:%s...\n",inifile); if (!tf.Open(inifile)) { sprintf(szBuf,"不能打开配置文件<%s>\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } g_LogFile.RemoveOverdueLogFile(tf.ReadInt("COMMON","LOGOVERDUE",10)); //g_BUnit.iBUnitGourpID = tf.ReadInt("COMMON","GID",1); tf.ReadString("COMMON","GID","",g_BUnit.szBUGroupID,sizeof(g_BUnit.szBUGroupID)-1); tf.ReadString("BCC","BCCSVR","127.0.0.1:6666",szBuf,sizeof(szBuf)-1); if (!tmpstr.FillStrings(szBuf,':') || tmpstr.GetCount()<2) { sprintf(szBuf,"配置文件<%s>的配置项[BCC] BCCSVR=???? 错误! 格式为:BCCSVR=xxx.xxx.xxx.xxx:port\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } strncpy(g_BUnit.szSvrIP,tmpstr.GetAt(0),sizeof(g_BUnit.szSvrIP)-1); g_BUnit.iSvrPort = atoi(tmpstr.GetAt(1)); g_BUnit.iHBInterval = tf.ReadInt("BCC","HEARTBEAT",5000); if (g_BUnit.iHBInterval<100) g_BUnit.iHBInterval = 100; g_ini_para.flash_dealy = tf.ReadInt("TIME", "INIT_DELAY", 60); g_ini_para.dynamic_load_flag = tf.ReadInt("DLLFLAG", "DYNAMIC_LOAD_FLAG", 0); g_ini_para.sysjones_func = tf.ReadInt("DLLFLAG", "SYNJONES_FUNC", 0); tf.ReadString("DLLFLAG", "CARDDLL", "", g_ini_para.third_part_dll_name, sizeof(g_ini_para.third_part_dll_name) - 1); g_ini_para.port = tf.ReadInt("THIRD_ACCOUNT", "PORT", 0); tf.ReadString("THIRD_ACCOUNT", "USER_ID", "", g_ini_para.user_id, sizeof(g_ini_para.user_id) - 1); tf.ReadString("THIRD_ACCOUNT", "USER_PWD", "", g_ini_para.encrypt_pwd, sizeof(g_ini_para.encrypt_pwd) - 1); tf.ReadString("THIRD_ACCOUNT", "IP", "", g_ini_para.ip, sizeof(g_ini_para.ip) - 1); tf.ReadString("DLLFLAG", "DESDLL", "", g_ini_para.des_dll_name, sizeof(g_ini_para.des_dll_name) - 1); g_ini_para.debug_log = tf.ReadInt("THIRD_ACCOUNT", "DEBUG_LOG", 0); g_ini_para.des_flag = tf.ReadInt("DLLFLAG", "DESDLL_FLAG", 0); tf.Close(); return(true); }
bool ReadIni(char *inifile) { TIniFile tf; CSList tmpstr; char szBuf[256]; memset(&g_BUnit,0,sizeof(g_BUnit)); printf("Begin to read ini-file:%s...\n",inifile); if (!tf.Open(inifile)) { sprintf(szBuf,"不能打开配置文件<%s>\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } g_LogFile.RemoveOverdueLogFile(tf.ReadInt("COMMON","LOGOVERDUE",10)); //g_BUnit.iBUnitGourpID = tf.ReadInt("COMMON","GID",1); tf.ReadString("COMMON","GID","",g_BUnit.szBUGroupID,sizeof(g_BUnit.szBUGroupID)-1); tf.ReadString("BCC","BCCSVR","127.0.0.1:6666",szBuf,sizeof(szBuf)-1); if (!tmpstr.FillStrings(szBuf,':') || tmpstr.GetCount()<2) { sprintf(szBuf,"配置文件<%s>的配置项[BCC] BCCSVR=???? 错误! 格式为:BCCSVR=xxx.xxx.xxx.xxx:port\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } strncpy(g_BUnit.szSvrIP,tmpstr.GetAt(0),sizeof(g_BUnit.szSvrIP)-1); g_BUnit.iSvrPort = atoi(tmpstr.GetAt(1)); g_BUnit.iHBInterval = tf.ReadInt("BCC","HEARTBEAT",5000); if (g_BUnit.iHBInterval<100) g_BUnit.iHBInterval = 100; tf.ReadString("DB2SVR","NAME","gmserver",g_BUnit.m_SqlDB.szServer,sizeof(g_BUnit.m_SqlDB.szServer)-1); tmpstr.trim(g_BUnit.m_SqlDB.szServer); tf.ReadString("DB2SVR","DATABASE","gmdata",g_BUnit.m_SqlDB.szDatabase,sizeof(g_BUnit.m_SqlDB.szDatabase)-1); tmpstr.trim(g_BUnit.m_SqlDB.szDatabase); tf.ReadString("DB2SVR","LOGIN","sa",g_BUnit.m_SqlDB.szLogin,sizeof(g_BUnit.m_SqlDB.szLogin)-1); tmpstr.trim(g_BUnit.m_SqlDB.szLogin); tf.ReadString("DB2SVR","PASSWORD","",g_BUnit.m_SqlDB.szPassword,sizeof(g_BUnit.m_SqlDB.szPassword)-1); tmpstr.trim(g_BUnit.m_SqlDB.szPassword); tf.Close(); return(true); }
// 2006-3-10 15:56:29 说是要增加一个能够将侦听和一个IP地址直接绑定,似乎为需要能够在一个指定网卡上侦听 bool CTcpSocket::Listen(short iPort,char *ip) { char err_msg[128] = ""; if (m_socket==INVALID_SOCKET) return(false); sockaddr_in addr; memset( &addr, 0, sizeof addr); addr.sin_family = m_nAddressFamily; addr.sin_port = htons(iPort); if (ip!=NULL) { unsigned int inaddr=inet_addr(ip); if (inaddr != INADDR_NONE) { memcpy(&(addr.sin_addr),&inaddr,sizeof(inaddr)); } } #ifndef WIN32 int flag=1; //addr.sin_addr.s_addr = htonl(INADDR_ANY); setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); #endif if (bind(m_socket, (struct sockaddr*)&addr, sizeof(addr))<0) { Close(); sprintf(err_msg, "can't bind socket from ip = [%s], port = [%d]", ip, iPort); DEBUG_RUNTIME_MSGOUT(err_msg); return(false); } if (listen(m_socket,TCP_LISTEN_NUM)) { Close(); sprintf(err_msg, "can't listen socket from ip = [%s], port = [%d]", ip, iPort); DEBUG_RUNTIME_MSGOUT(err_msg); return(false); } return(true); }
int CSvrLink::IntCall(char *szBUGroupID, int waittime, ST_CPACK *rpack, ST_CPACK *apack, ST_PACK *pArrays) { int rtn; unsigned short len; unsigned char sbuf[MAXMSG]; char szmsg[256]={0}; RP_INTCALLH *pic = (RP_INTCALLH *)sbuf; pic->waittime = htonl(waittime); strncpy(pic->szBUGroupID,szBUGroupID,MAXBUGRPID); if (rpack->head.recCount>1) { rpack->head.recCount = 1; } EncodeBuf(rpack,sbuf+sizeof(RP_INTCALLH),&rtn,szmsg); len = rtn+sizeof(RP_INTCALLH); rtn=SendMsg(MT_INTCALL,len,sbuf); while (rtn==0) { rtn = RecvMsg(waittime*1000+1000); if (rtn>0) { MSGBUF *pmb = GetRecvMsg(); if (pmb->head.msgtype==MT_PUSHDATA) { // 有应答数据返回: rtn = 0; DecodeBufWithArray((unsigned char *)pmb->data,pmb->head.len,apack,pArrays,&rtn,szmsg); //memset(&xcdata,0,sizeof(xcdata)); // 清空 memcpy(&(xcdata.ahead),&(apack->head),sizeof(ST_PACKHEAD)); if (pmb->head.len>=rtn+sizeof(TPUSHDESTN)) { TPUSHDESTN *pd = (TPUSHDESTN *)(pmb->data+rtn); xcdata.sno = ntohs(pd->SourceNo); xcdata.dno = ntohs(pd->DestNo); xcdata.fno = ntohs(pd->FuncNo); } return(rtn); } else { DEBUG_RUNTIME_MSGOUT("IntCall中间收到了非MT_INTCALL应答包,属于程序错误!"); rtn = 0; // 继续读取数据,以便接收到正确的MT_INTCALL应答包 } } else if (rtn==0) { return(-2); // 等待应答数据超时,即自从向外发送了请求后,在waittime+1秒内没有接收到应答数据 } } return(-1); // 其他各种通讯方面的错误 }
// 函数名: CSvrLink::DataDone // 编程 : 陈永华 2004-2-22 13:35:51 // 描述 : // 返回 : int int CSvrLink::DataDone(int retcode,char *szMsg) { char buf[MAXMSG]; RP_DATADONE *pad=(RP_DATADONE *)buf; #ifdef TESTINFO sprintf(buf,"功能号(%u)处理结果(%d):%s",iLastReqType,retcode,szMsg); DEBUG_RUNTIME_MSGOUT(buf); #endif pad->iLastReqType = htonl(iLastReqType); pad->n_retcode = htonl(retcode); strcpy(pad->szmsg,szMsg); return(SendMsg(MT_DATADONE,sizeof(RP_DATADONE)+strlen(szMsg),buf)); }
bool ReadIni(char *inifile) { TIniFile tf; CSList tmpstr; char szBuf[256]; g_LogFile.Open("bulog"); // 用程序的进程号作为各个BU日志文件存放目录 memset(&g_BUnit,0,sizeof(g_BUnit)); printf("Begin to read ini-file:%s...\n",inifile); if (!tf.Open(inifile)) { sprintf(szBuf,"不能打开配置文件<%s>\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } g_LogFile.RemoveOverdueLogFile(tf.ReadInt("COMMON","LOGOVERDUE",10)); //g_BUnit.iBUnitGourpID = tf.ReadInt("COMMON","GID",1); tf.ReadString("COMMON","GID","",g_BUnit.szBUGroupID,sizeof(g_BUnit.szBUGroupID)-1); tf.ReadString("BCC","BCCSVR","127.0.0.1:6666",szBuf,sizeof(szBuf)-1); if (!tmpstr.FillStrings(szBuf,':') || tmpstr.GetCount()<2) { sprintf(szBuf,"配置文件<%s>的配置项[BCC] BCCSVR=???? 错误! 格式为:BCCSVR=xxx.xxx.xxx.xxx:port\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } strncpy(g_BUnit.szSvrIP,tmpstr.GetAt(0),sizeof(g_BUnit.szSvrIP)-1); g_BUnit.iSvrPort = atoi(tmpstr.GetAt(1)); g_BUnit.iHBInterval = tf.ReadInt("BCC","HEARTBEAT",5000); if (g_BUnit.iHBInterval<100) g_BUnit.iHBInterval = 100; g_ini_para.flash_dealy = tf.ReadInt("TIME", "INIT_DELAY", 60); tf.Close(); return(true); }
int CSvrLink::ExtCall(int sourceno, int destno, int funcno, int batchno, int acktime, ST_CPACK *rpack, ST_CPACK *apack, ST_PACK *pArrays) { int rtn; char szmsg[256]; xcdata.sno = sourceno; xcdata.dno = destno; xcdata.fno = funcno; xcdata.bno = batchno; rpack->head.userdata = batchno; if (acktime<=0) { acktime = 5; // 缺省为5秒钟内得到应答,否则作为失败处理。。。以防止业务部分调用错误导致整个BUNIT处理失败或挂起 } rtn = PushData(sourceno,destno,funcno,batchno,rpack,PM_ANSWER,acktime); while (rtn==0) { rtn = RecvMsg(acktime*1000+1000); if (rtn>0) { MSGBUF *pmb = GetRecvMsg(); if (pmb->head.msgtype==MT_PUSHDATA) { // 有应答数据返回: rtn = 0; DecodeBufWithArray((unsigned char *)pmb->data,pmb->head.len,apack,pArrays,&rtn,szmsg); memcpy(&xcdata.ahead,&(apack->head),sizeof(ST_PACKHEAD)); if (apack->head.hook.queuetype>0) xcdata.fno = apack->head.hook.queuetype; else if (atoi(apack->head.hook.hostname)>0) xcdata.fno = atoi(apack->head.hook.hostname); return(rtn); } else { DEBUG_RUNTIME_MSGOUT("ExtCall中间收到了非MT_PUSHDATA应答包,属于程序错误!"); rtn = 0; // 继续读取数据,以便接收到正确的MT_PUSHDATA应答包 } } else if (rtn==0) { return(-2); // 等待应答数据超时,即自从向外发送了请求后,在acktime+1秒内没有接收到应答数据 } } return(-1); // 其他各种通讯方面的错误 }
// 函数名: CSvrLink::RecvMsg // 编程 : 陈永华 2004-2-10 22:40:18 // 描述 : 按照MSG协议接收数据 // 返回 : int >0:接收到正常数据包;0:超时;-1:被对方正常关闭;-10:输入的nDesignedSize<=0;-11:对方非标准MSG协议口或数据不同步;-2:因为链路错误而被关闭;-3:在接收数据的时候,出错而被关闭 // 参数 : int timeout int CSvrLink::RecvMsg(int timeout) { MSGBUF *pMsgBuf=(MSGBUF *)buf; MSGHEAD *phead = (MSGHEAD *)buf; int rtn; bool bReverse; rtn = linksock.Recv(buf,sizeof(MSGHEAD),timeout); if (rtn!=sizeof(MSGHEAD)) return(rtn); // 接收时候出错,或超时 if (phead->msgid==RMSGID) { bReverse = true; reverse(&(phead->msgid),sizeof(phead->msgid)); reverse(&(phead->msgtype),sizeof(phead->msgtype)); reverse(&(phead->len),sizeof(phead->len)); } else bReverse = false; if (phead->msgid!=LMSGID || phead->len>MAXMSG) { // 属于不正常的MSG,关闭端口,重新连接。。。 // 或者数据流不同步,通过重新连接进行同步。。。 DEBUG_RUNTIME_MSGOUT("属于不正常的MSG或者数据流不同步,关闭端口,重新连接\n"); linksock.Close(); return(-11); } if (phead->len>0) { rtn = linksock.Recv(pMsgBuf->data,phead->len,5000); // 一直等待到接收到后续数据,或出错,或5秒钟超时 if (rtn!=phead->len) { linksock.Close(); return(rtn); // 接收时候出错,或超时 } } m_lastrcvtick = GetTickCount(); return(phead->len+sizeof(MSGHEAD)); }
// 函数名: CSvrLink::DataDone // 编程 : 陈永华 2004-2-22 13:35:51 // 描述 : // 返回 : int int CSvrLink::DataDone(int retcode,char *szMsg) { char buf[MAXMSG]; RP_DATADONE *pad=(RP_DATADONE *)buf; #ifdef TESTINFO sprintf(buf,"功能号(%u)处理结果(%d):%s",iLastReqType,retcode,szMsg); DEBUG_RUNTIME_MSGOUT(buf); #endif /* ****** Updated by CHENYH at 2006-2-9 17:26:16 ****** 集中交易即使没有记录也需要相应的位图 *******************************************************/ if (head.recCount<=0) { SendMsg(MT_SETCOL,sizeof(head.ParmBits),head.ParmBits); // 先提供后续数据记录的位图 head.recCount = 0; } /******************************************************/ pad->iLastReqType = htonl(iLastReqType); pad->n_retcode = htonl(retcode); strcpy(pad->szmsg,szMsg); return(SendMsg(MT_DATADONE,sizeof(RP_DATADONE)+strlen(szMsg),buf)); }
int main(int argc,char *argv[]) { int rtn; openlog("yktbu",LOG_PID|LOG_CONS|LOG_NDELAY,LOG_LOCAL0); g_pSvrLink = BUPubInitialize(g_XBDefines,CallBDFunc,WriteAppInfo,&g_LogFile); SetLogShowLevel(0); sprintf(g_szVerNo,"%s %s (%s)",argv[0],YKT_VERSION,__DATE__); if(argc==2) { if(strncmp(argv[1],"-v",2)==0||strncmp(argv[1],"-V",2)==0) { printf("%s\n",g_szVerNo); closelog(); return 0; } } if (argc<2) ReadIni("ksbu.ini"); else ReadIni(argv[1]); ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } // 初始化数据库连接: SQLInitialize(); if (SQLConnectToServer()!=0) { DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); return(-100); } DEBUG_RUNTIME_MSGOUT("连接数据库成功!\n"); CAccTrans& ats=CAccTrans::GetInst(); if(ats.LoadCfg()!=0) { DEBUG_RUNTIME_MSGOUT("加载系统参数失败!\n"); //RAISE_RUNTIME_ERROR("加载数据库账务配置参数失败!\n"); return(-200); } DEBUG_RUNTIME_MSGOUT("加载系统参数成功!\n"); // 初始化与BCC连接: do { rtn = g_pSvrLink->ToLink(&g_BUnit); if (rtn==1) { DEBUG_RUNTIME_MSGOUT("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); mysleep(g_BUnit.iHBInterval); } else { // 应该属于故障,或对方并不是BCC return(rtn); } } while (1); #ifdef WIN32 setnoblockgetch(); #endif while (g_pSvrLink->LinkOK()) { #ifdef WIN32 switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:"); break; case 'x': case 'X': g_pSvrLink->bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } #endif if (!SQLIsConnectOK()) { mysleep(1000); if (!g_pSvrLink->CheckLink()) break; // BCC exit (可能用户发现数据库连接断开,需要维护系统,导致手工将BCC退出同时也需要BU退出) if (SQLConnectToServer()!=0) { // SQL Link error: DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); } else { DEBUG_RUNTIME_MSGOUT("与数据库连接成功!\n"); } continue; } else g_pSvrLink->Processing(&g_BUnit); if (g_pSvrLink->bExit) break; } /* ****** Updated by CHENYH at 2004-4-14 11:07:19 ****** 经过测试后,CheckLink()工作正常,测试环境为:BCC(WIN)+BU(WIN),BCC(LINUX)+BU(WIN),BCC(LINUX)+BU(LINUX) while (1) { mysleep(1000); if (!g_SvrLink.CheckLink()) { printf("TEST CHECK LINK return <false>!\n"); break; } } */ g_pSvrLink->Close(); SQLExit(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); closelog(); return(0); }
bool ReadIni(char *inifile) { TIniFile tf; CSList tmpstr; char szBuf[256]; g_LogFile.Open("bulog"); // 用程序的进程号作为各个BU日志文件存放目录 memset(&g_BUnit,0,sizeof(g_BUnit)); printf("Begin to read ini-file:%s...\n",inifile); if (!tf.Open(inifile)) { sprintf(szBuf,"不能打开配置文件<%s>\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } g_LogFile.RemoveOverdueLogFile(tf.ReadInt("COMMON","LOGOVERDUE",10)); //g_BUnit.iBUnitGourpID = tf.ReadInt("COMMON","GID",1); tf.ReadString("COMMON","GID","",g_BUnit.szBUGroupID,sizeof(g_BUnit.szBUGroupID)-1); tf.ReadString("BCC","BCCSVR","127.0.0.1:6666",szBuf,sizeof(szBuf)-1); if (!tmpstr.FillStrings(szBuf,':') || tmpstr.GetCount()<2) { sprintf(szBuf,"配置文件<%s>的配置项[BCC] BCCSVR=???? 错误! 格式为:BCCSVR=xxx.xxx.xxx.xxx:port\n",inifile); DEBUG_RUNTIME_MSGOUT(szBuf); exit(-1000); } strncpy(g_BUnit.szSvrIP,tmpstr.GetAt(0),sizeof(g_BUnit.szSvrIP)-1); g_BUnit.iSvrPort = atoi(tmpstr.GetAt(1)); g_BUnit.iHBInterval = tf.ReadInt("BCC","HEARTBEAT",5000); if (g_BUnit.iHBInterval<100) g_BUnit.iHBInterval = 100; /* ****** Updated by CHENYH at 2005-9-28 12:14:22 ****** tf.ReadString("SQLSVR","NAME","gmserver",g_BUnit.m_SqlDB.szServer,sizeof(g_BUnit.m_SqlDB.szServer)-1); tmpstr.trim(g_BUnit.m_SqlDB.szServer); tf.ReadString("SQLSVR","DATABASE","gmdata",g_BUnit.m_SqlDB.szDatabase,sizeof(g_BUnit.m_SqlDB.szDatabase)-1); tmpstr.trim(g_BUnit.m_SqlDB.szDatabase); tf.ReadString("SQLSVR","LOGIN","sa",g_BUnit.m_SqlDB.szLogin,sizeof(g_BUnit.m_SqlDB.szLogin)-1); tmpstr.trim(g_BUnit.m_SqlDB.szLogin); tf.ReadString("SQLSVR","PASSWORD","",g_BUnit.m_SqlDB.szPassword,sizeof(g_BUnit.m_SqlDB.szPassword)-1); tmpstr.trim(g_BUnit.m_SqlDB.szPassword); *******************************************************/ tf.ReadString("DB2SVR","NAME","gmserver",g_SqlDB.szServer,sizeof(g_SqlDB.szServer)-1); tmpstr.trim(g_SqlDB.szServer); memset(szBuf,0,sizeof szBuf); tf.ReadString("DB2SVR","AUTH_TYPE","config",szBuf,sizeof(szBuf)-1); if(strcmp("config",szBuf) == 0) { // 从配置文件读取 tf.ReadString("DB2SVR","DATABASE","gmdata",g_SqlDB.szDatabase,sizeof(g_SqlDB.szDatabase)-1); tmpstr.trim(g_SqlDB.szDatabase); tf.ReadString("DB2SVR","LOGIN","sa",g_SqlDB.szLogin,sizeof(g_SqlDB.szLogin)-1); tmpstr.trim(g_SqlDB.szLogin); tf.ReadString("DB2SVR","PASSWORD","",g_SqlDB.szPassword,sizeof(g_SqlDB.szPassword)-1); tmpstr.trim(g_SqlDB.szPassword); } else if(strcmp("env",szBuf) == 0) { // 从环境变量读取 char* penv=NULL; if((penv = getenv("YKT_DBNAME")) == NULL) { DEBUG_RUNTIME_MSGOUT("无法取得数据库名"); exit(-1001); } strcpy(g_SqlDB.szDatabase,penv); tmpstr.trim(g_SqlDB.szDatabase); if((penv = getenv("YKT_USER")) == NULL) { DEBUG_RUNTIME_MSGOUT("无法取得数据库连接用户名"); exit(-1001); } strcpy(g_SqlDB.szLogin,penv); tmpstr.trim(g_SqlDB.szLogin); if((penv = getenv("YKT_PWD")) == NULL) { DEBUG_RUNTIME_MSGOUT("无法取得数据库连接密码"); exit(-1001); } strcpy(g_SqlDB.szPassword,penv); tmpstr.trim(g_SqlDB.szPassword); } else { DEBUG_RUNTIME_MSGOUT("数据库连接方式配置错误\n"); exit(-1001); } tf.Close(); return(true); }
int main(int argc, char* argv[]) { ::CoInitialize(NULL); // 结合SQL SERVER2000使用 int rtn = 0; time_t cur_time; time_t last_time; time(&last_time); g_pSvrLink = BUPubInitialize(g_XBDefines,CallBDFunc,WriteAppInfo,&g_LogFile); SetLogShowLevel(0); if (argc<2) ReadIni("ksbu.ini"); else ReadIni(argv[1]); ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } #ifdef _DYNAMIC_LOAD // 加载对接第三方动态库 if (rtn = g_LoadDll.LoadDataInfo("DataInfo.dll")) { g_LogFile.WriteLogEx(1002, "加载DataInfo.dll失败--错误码:[%d]", rtn); return rtn; } g_LogFile.WriteLogEx(1002, "加载DataInfo.dll成功"); #endif // 初始化第三方数据库信息 #ifdef SYNJONES_FUNC if (rtn = InitDB()) { g_LogFile.WriteLogEx(1002, "初始化第三方数据库失败--错误码:[%d]", rtn); return rtn; } g_LogFile.WriteLogEx(1002, "初始化第三方数据库成功"); #endif // 初始化与BCC连接: do { rtn = g_pSvrLink->ToLink(&g_BUnit); if (rtn==1) { DEBUG_RUNTIME_MSGOUT("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); mysleep(g_BUnit.iHBInterval); } else { // 应该属于故障,或对方并不是BCC return(rtn); } } while (1); #ifdef WIN32 setnoblockgetch(); #endif while (g_pSvrLink->LinkOK()) { #ifdef WIN32 switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:"); break; case 'x': case 'X': g_pSvrLink->bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } #endif time(&cur_time); if (cur_time - last_time > g_ini_para.flash_dealy) { if (rtn = InitDB()) { g_LogFile.WriteLogEx(1002, "初始化数据库失败:[%d]", rtn); } last_time = cur_time; g_LogFile.WriteLogEx(1002, "初始化数据库成功:[%d]", rtn); } g_pSvrLink->Processing(&g_BUnit); if (g_pSvrLink->bExit) break; } g_pSvrLink->Close(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); #ifdef _DYNAMIC_LOAD CloseDB(); g_LoadDll.UnLoadAllDll(); #endif ::CoUninitialize(); return(0); }
int main(int argc,char *argv[]) { int rtn; openlog("buencsvr",LOG_PID|LOG_CONS|LOG_NDELAY,LOG_LOCAL0); g_pSvrLink = BUPubInitialize(g_XBDefines,CallBDFunc,WriteAppInfo,&g_LogFile); SetLogShowLevel(0); sprintf(g_szVerNo,"%s %s (%s)",argv[0],YKT_VERSION,__DATE__); if(argc==2) { if(strncmp(argv[1],"-v",2)==0||strncmp(argv[1],"-V",2)==0) { printf("%s\n",g_szVerNo); closelog(); return 0; } } BKConfiguration::instance()->load_config(); if (argc<2) ReadIni("ksbu.ini"); else ReadIni(argv[1]); ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } DEBUG_RUNTIME_MSGOUT("加载系统参数成功!\n"); // 初始化与BCC连接: do { rtn = g_pSvrLink->ToLink(&g_BUnit); if (rtn==1) { DEBUG_RUNTIME_MSGOUT("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); mysleep(g_BUnit.iHBInterval); } else { // 应该属于故障,或对方并不是BCC return(rtn); } } while (1); #ifdef WIN32 setnoblockgetch(); #endif while (g_pSvrLink->LinkOK()) { #ifdef WIN32 switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:"); break; case 'x': case 'X': g_pSvrLink->bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } #endif g_pSvrLink->Processing(&g_BUnit); if (g_pSvrLink->bExit) break; } g_pSvrLink->Close(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); closelog(); return(0); }
int main(int argc,char *argv[]) { int rtn; pSqlDB = &(g_BUnit.m_SqlDB); // 供外部方便检查,主要用于DEBUGSQLERROR(msg) g_BUnit.pSvrLink = &g_SvrLink; g_LogFile.SetFlushDelay(0); g_LogFile.Open("bulog"); openlog("yktbase",LOG_PID|LOG_CONS|LOG_NDELAY,LOG_LOCAL0); memset(pSqlDB,0,sizeof(ST_SQLDB)); //puts("Before Reading ini..."); if (argc<2) ReadIni("fdsvrall.ini"); else ReadIni(argv[1]); DEBUG_RUNTIME_MSGOUT("读配置文件end"); ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } pSqlDB->bConnected = 0; // 初始化数据库连接: SQLInitialize(); if (SQLConnectToServer()!=0) { DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); g_LogFile.Close(); closelog(); return(-100); } #ifndef WIN32 struct sigaction sigact; memset(&sigact,0,sizeof sigact); sigact.sa_handler = sig_alarm_handler; sigaction(SIGALRM,&sigact,NULL); #endif // 初始化与BCC连接: DEBUG_RUNTIME_MSGOUT("连接数据库成功!\n"); do { rtn = g_SvrLink.ToLink(&g_BUnit); if (rtn==1) { puts("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); puts("sleep waiting for connect BCC!"); mysleep(g_BUnit.iHBInterval); } else { g_LogFile.Close(); closelog(); return(rtn); } } while (1); setnoblockgetch(); while (g_SvrLink.LinkOK()) { /* switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:\n"); break; case 'x': case 'X': g_SvrLink.bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } */ TestSQLConnect(); if (pSqlDB->bConnected==0) { mysleep(1000); if (!g_SvrLink.CheckLink()) break; // BCC exit (可能用户发现数据库连接断开,需要维护系统,导致手工将BCC退出同时也需要BU退出) if (SQLConnectToServer()!=0) { // SQL Link error: DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); } else { DEBUG_RUNTIME_MSGOUT("与数据库连接成功!\n"); } continue; } else g_SvrLink.Processing(&g_BUnit); if (g_SvrLink.bExit) break; } /* ****** Updated by CHENYH at 2004-4-14 11:07:19 ****** 经过测试后,CheckLink()工作正常,测试环境为:BCC(WIN)+BU(WIN),BCC(LINUX)+BU(WIN),BCC(LINUX)+BU(LINUX) while (1) { mysleep(1000); if (!g_SvrLink.CheckLink()) { printf("TEST CHECK LINK return <false>!\n"); break; } } */ g_SvrLink.Close(); closelog(); SQLExit(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); return(0); }
int main(int argc,char *argv[]) { int rtn; int ret=0; openlog("yktbank",LOG_PID|LOG_CONS|LOG_NDELAY,LOG_LOCAL3); g_pSvrLink = BUPubInitialize(g_XBDefines,CallBDFunc,WriteAppInfo,&g_LogFile); SetLogShowLevel(0); if (argc<2) ReadIni("ksbu.ini"); else ReadIni(argv[1]); struct sigaction act,oldact; act.sa_handler = handler_alarm; if(-1==sigaction(SIGALRM,&act,&oldact)) { writelog(LOG_ERR,"sigaction error,errcode=[%d]",-1); return -1; } ret=ReadIni_bank(&g_Bank); if(ret) { writelog(LOG_ERR,"ReadIni_bank error,errcode=[%d]",ret); return -1; } ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } // 初始化数据库连接: /* SQLInitialize(); if (SQLConnectToServer()!=0) { RAISE_RUNTIME_ERROR("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); return(-100); } */ // 初始化与BCC连接: do { rtn = g_pSvrLink->ToLink(&g_BUnit); if (rtn==1) { DEBUG_RUNTIME_MSGOUT("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); mysleep(g_BUnit.iHBInterval); } else { // 应该属于故障,或对方并不是BCC DEBUG_RUNTIME_MSGOUT("未知错误\n"); return(rtn); } } while (1); #ifdef WIN32 setnoblockgetch(); #endif /********************************************************************** Added by hhd at 2004-09-16 为了增加签到处理,达到共享内存的处理 增加共享内存和信号量 共享内存一共1024个字节,其中使用前18个字节 shm[0]:代表是否进行过签到的标志,如果为1,已经签过到但不知道是否成功 ,后续业务将不能进行签到处理,如果为其他值,系统将进行签到 shm[1]:代表签到是否成功的标志,如果为1,则标识签到成功,后续16个字节为 银行正常返回数据,可以使用 shm[2~17]:前8个字节为加密的PIN密钥,后8个字节为加密的MAC密钥 ***********************************************************************/ /********************************************************************** Update by hhd at 2004-10-27 为了增加签到处理,达到共享内存的处理 增加共享内存和信号量 为了反映每个终端的当前工作状态,在共享内存中设置一个状态标志 共享内存一共1024个字节,其中使用前26个字节 shm[0]:代表是否进行过签到的标志,如果为1,已经签过到但不知道是否成功 ,后续业务将不能进行签到处理,如果为其他值,系统将进行签到 shm[1]:代表签到是否成功的标志,如果为1,则标识签到成功,后续16个字节为 银行正常返回数据,可以使用 shm[2]:代表系统重新启动标志,如果不为1,系统进行初始化操作(进行设备 注册表中设备的状态的清空操作),然后系统将改标志置为1,其他BU启动 跳过该项操作 shm[10~25]:前8个字节为加密的PIN密钥,后8个字节为加密的MAC密钥 ***********************************************************************/ /* key_t key; struct shmid_ds buf; // Update by lq at 2005-03-10 // 将创建共享内存和设备签到移到bankguard中去 // 必须先运行bankguard此处操作才能完成 key=ftok("bankguard",9); shmid=shmget(key,SEGSIZE,0666); if(-1==shmid) { printf("errno=%s\n",strerror(errno)); DEBUG_RUNTIME_MSGOUT("获取共享内存失败,请确保bankguard已经启动\n"); return E_CREATE_SHARE_MEMORY; } shm=(char*)shmat(shmid,0,0); if((int)shm==-1) { DEBUG_RUNTIME_MSGOUT("映射共享内存失败"); return E_JOIN_SHARE_MEMORY; } semid=semget(key,1,0); if(semid==-1) { DEBUG_RUNTIME_MSGOUT("获取共享锁id失败"); return E_JOIN_SHARE_MEMORY; } */ // Added by hhd end here while (g_pSvrLink->LinkOK()) { #ifdef WIN32 switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:"); break; case 'x': case 'X': g_pSvrLink->bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } #endif // if (!SQLIsConnectOK()) if(0) { mysleep(1000); if (!g_pSvrLink->CheckLink()) break; // BCC exit (可能用户发现数据库连接断开,需要维护系统,导致手工将BCC退出同时也需要BU退出) //if (SQLConnectToServer()!=0) if(0) { // SQL Link error: DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); } else { DEBUG_RUNTIME_MSGOUT("与数据库连接成功!\n"); } continue; } else { //DEBUG_RUNTIME_MSGOUT("处理bu业务!\n"); g_pSvrLink->Processing(&g_BUnit); } //if (g_pSvrLink->bExit) break; } /* ****** Updated by CHENYH at 2004-4-14 11:07:19 ****** 经过测试后,CheckLink()工作正常,测试环境为:BCC(WIN)+BU(WIN),BCC(LINUX)+BU(WIN),BCC(LINUX)+BU(LINUX) while (1) { mysleep(1000); if (!g_SvrLink.CheckLink()) { printf("TEST CHECK LINK return <false>!\n"); break; } } */ /* shmdt(shm); shmctl(shmid,IPC_RMID,&buf); d_sem(semid); */ g_pSvrLink->Close(); // SQLExit(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); closelog(); return(0); }
int CSvrLink::ExtCall(int sourceno, int destno, int funcno, int batchno, int acktime, void *rdata, int rdlen, char *abuf, int &alen) { int rtn; char szmsg[256]; ST_PACKHEAD phead; xcdata.sno = sourceno; xcdata.dno = destno; xcdata.fno = funcno; xcdata.bno = batchno; DecodeHead((unsigned char *)rdata,rdlen,&phead,szmsg); phead.userdata = batchno; ModifyHead(&phead,(unsigned char *)rdata); if (acktime<=0) { acktime = 5; // 缺省为5秒钟内得到应答,否则作为失败处理。。。以防止业务部分调用错误导致整个BUNIT处理失败或挂起 } rtn = PushData(sourceno,destno,funcno,batchno,PM_ANSWER,acktime,rdata,rdlen); while (rtn==0) { rtn = RecvMsg(acktime*1000+1000); if (rtn>0) { MSGBUF *pmb = GetRecvMsg(); if (pmb->head.msgtype==MT_PUSHDATA) { // 有应答数据返回: alen = pmb->head.len; memcpy(abuf,pmb->data,alen); DecodeHead((unsigned char *)abuf,alen,&(xcdata.ahead),szmsg); // 为了正确提取外调功能的后续包(尤其对BCC能够支持并行多应用服务器架构),则采用 if (xcdata.ahead.hook.queuename[0]>='0' && xcdata.ahead.hook.queuename[0]<='9' && xcdata.ahead.hook.queuetype>0) { // 属于KSBCC模式的XPACK协议: xcdata.fno = xcdata.ahead.hook.queuetype; // 包括能够处理被目标点转发后处理的请求 if (0==xcdata.ahead.hook.hostname[0]) { int dno = atoi(xcdata.ahead.hook.hostname+1); if (dno>0) { xcdata.dno = dno; } } // m_bBCCADP: 2006-3-17 17:14:21 else if (0!=xcdata.ahead.hook.hostname[10]) { int dno = atoi(xcdata.ahead.hook.hostname+10); if (dno>0) { xcdata.dno = dno; } } ////////////////////////////////////////////////////////////////////////// } return(rtn); } else { DEBUG_RUNTIME_MSGOUT("ExtCall中间收到了非MT_PUSHDATA应答包,属于程序错误!"); rtn = 0; // 继续读取数据,以便接收到正确的MT_PUSHDATA应答包 } } else if (rtn==0) { return(-2); // 等待应答数据超时,即自从向外发送了请求后,在acktime+1秒内没有接收到应答数据 } } return(-1); // 其他各种通讯方面的错误 }
int main(int argc,char *argv[]) { int rtn; pSqlDB = &(g_BUnit.m_SqlDB); // 供外部方便检查,主要用于DEBUGSQLERROR(msg) g_BUnit.pSvrLink = &g_SvrLink; g_LogFile.SetFlushDelay(0); g_LogFile.Open("bulog"); memset(pSqlDB,0,sizeof(ST_SQLDB)); openlog("fdykt_hhd",LOG_PID|LOG_CONS|LOG_NDELAY,LOG_LOCAL4); puts("Before Reading ini..."); if (argc<2) ReadIni("fdsvrall.ini"); else ReadIni(argv[1]); puts("读配置文件end!\n"); DEBUG_RUNTIME_MSGOUT("读配置文件end"); ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } pSqlDB->bConnected = 0; // 初始化数据库连接: SQLInitialize(); if (SQLConnectToServer()!=0) { DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); return(-100); } // 初始化与BCC连接: DEBUG_RUNTIME_MSGOUT("连接数据库成功!\n"); do { rtn = g_SvrLink.ToLink(&g_BUnit); if (rtn==1) { DEBUG_RUNTIME_MSGOUT("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); puts("sleep waiting for connect BCC!"); mysleep(g_BUnit.iHBInterval); } else { // 应该属于故障,或对方并不是BCC DEBUG_RUNTIME_MSGOUT("未知错误\n"); return(rtn); } } while (1); setnoblockgetch(); /********************************************************************** Added by hhd at 2004-09-16 为了增加签到处理,达到共享内存的处理 增加共享内存和信号量 共享内存一共1024个字节,其中使用前18个字节 shm[0]:代表是否进行过签到的标志,如果为1,已经签过到但不知道是否成功 ,后续业务将不能进行签到处理,如果为其他值,系统将进行签到 shm[1]:代表签到是否成功的标志,如果为1,则标识签到成功,后续16个字节为 银行正常返回数据,可以使用 shm[2~17]:前8个字节为加密的PIN密钥,后8个字节为加密的MAC密钥 ***********************************************************************/ /********************************************************************** Update by hhd at 2004-10-27 为了增加签到处理,达到共享内存的处理 增加共享内存和信号量 为了反映每个终端的当前工作状态,在共享内存中设置一个状态标志 共享内存一共1024个字节,其中使用前26个字节 shm[0]:代表是否进行过签到的标志,如果为1,已经签过到但不知道是否成功 ,后续业务将不能进行签到处理,如果为其他值,系统将进行签到 shm[1]:代表签到是否成功的标志,如果为1,则标识签到成功,后续16个字节为 银行正常返回数据,可以使用 shm[2]:代表系统重新启动标志,如果不为1,系统进行初始化操作(进行设备 注册表中设备的状态的清空操作),然后系统将改标志置为1,其他BU启动 跳过该项操作 shm[10~25]:前8个字节为加密的PIN密钥,后8个字节为加密的MAC密钥 ***********************************************************************/ key_t key; int ret=0; struct shmid_ds buf; // Update by lq at 2005-03-10 // 将创建共享内存和设备签到移到bankguard中去 // 必须先运行bankguard此处操作才能完成 key=ftok(".",0); shmid=shmget(key,SEGSIZE,0666); if(-1==shmid) { DEBUG_RUNTIME_MSGOUT("获取共享内存失败,请确保bankguard已经启动\n"); return E_CREATE_SHARE_MEMORY; } shm=(char*)shmat(shmid,0,0); if((int)shm==-1) { DEBUG_RUNTIME_MSGOUT("映射共享内存失败"); return E_JOIN_SHARE_MEMORY; } semid=semget(key,1,0); if(semid==-1) { DEBUG_RUNTIME_MSGOUT("获取共享锁id失败"); return E_JOIN_SHARE_MEMORY; } while (g_SvrLink.LinkOK()) { switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:\n"); break; case 'x': case 'X': g_SvrLink.bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } TestSQLConnect(); if (pSqlDB->bConnected==0) //这个变量有人维护吗? { mysleep(1000); if (!g_SvrLink.CheckLink()) break; // BCC exit (可能用户发现数据库连接断开,需要维护系统,导致手工将BCC退出同时也需要BU退出) if (SQLConnectToServer()!=0) { // SQL Link error: DEBUG_RUNTIME_MSGOUT("不能正常建立数据库连接, 检查配置和数据库服务器!\n"); } else { DEBUG_RUNTIME_MSGOUT("与数据库连接成功!\n"); } continue; } else g_SvrLink.Processing(&g_BUnit); if (g_SvrLink.bExit) break; } /* ****** Updated by CHENYH at 2004-4-14 11:07:19 ****** 经过测试后,CheckLink()工作正常,测试环境为:BCC(WIN)+BU(WIN),BCC(LINUX)+BU(WIN),BCC(LINUX)+BU(LINUX) while (1) { mysleep(1000); if (!g_SvrLink.CheckLink()) { printf("TEST CHECK LINK return <false>!\n"); break; } } */ shmdt(shm); shmctl(shmid,IPC_RMID,&buf); d_sem(semid); closelog(); g_SvrLink.Close(); SQLExit(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); return(0); }
int main(int argc, char* argv[]) { ::CoInitialize(NULL); // 结合SQL SERVER2000使用 int rtn; char msg[256] = ""; char *result = NULL; g_pSvrLink = BUPubInitialize(g_XBDefines,CallBDFunc,WriteAppInfo,&g_LogFile); SetLogShowLevel(0); if (argc<2) ReadIni("ksbu.ini"); else ReadIni(argv[1]); ResetBPFunctions(); if (argc>2) { ListBPFunctions(argv[2]); } if (g_ini_para.dynamic_load_flag) { // 加载对接第三方动态库 if (rtn = g_LoadDll.LoadDataInfo(g_ini_para.third_part_dll_name, THIRD_RG_DLL)) { sprintf(msg, "加载%s失败--错误码:[%d]", g_ini_para.third_part_dll_name, rtn); g_LogFile.WriteLogEx(1002, msg); return rtn; } } // 加载desdll库 if (g_ini_para.des_flag) { if (rtn = g_desdll.LoadDataInfo(g_ini_para.des_dll_name, DESDLL)) { sprintf(msg, "加载%s失败--错误码:[%d]", g_ini_para.des_dll_name, rtn); g_LogFile.WriteLogEx(1002, msg); return rtn; } // encrypt_work_key_asc(g_ini_para.pwd, g_ini_para.encrypt_pwd); decrypt_work_key_asc(g_ini_para.encrypt_pwd, g_ini_para.pwd); } if (g_ini_para.debug_log) { g_LogFile.WriteLogEx(1003, "用户名[%s]--原始密码[%s]--加密密码[%s]--IP地址[%s]--端口号[%d]", g_ini_para.user_id, g_ini_para.pwd, g_ini_para.encrypt_pwd,g_ini_para.ip, g_ini_para.port); sprintf(msg, "加载%s成功", g_ini_para.third_part_dll_name); g_LogFile.WriteLogEx(1002, msg); } if (g_ini_para.sysjones_func) { result = fInit(); if (strncmp(result, RG_SUCC, RG_FLAG_LEN)) { sprintf(msg, "初始化第三方数据库失败--错误码:[%d]", rtn); g_LogFile.WriteLogEx(1002, msg); return rtn; } g_LogFile.WriteLogEx(1002, "初始化第三方数据库成功"); } // 初始化与BCC连接: do { rtn = g_pSvrLink->ToLink(&g_BUnit); if (rtn==1) { DEBUG_RUNTIME_MSGOUT("与业务调度中心(BCC)的连接成功!\n"); break; } else if (rtn==-100) { DEBUG_RUNTIME_MSGOUT("估计业务调度中心(BCC)尚未正式启动,或者检查配置中的[SERVER]项参数\n"); mysleep(g_BUnit.iHBInterval); } else { // 应该属于故障,或对方并不是BCC return(rtn); } } while (1); #ifdef WIN32 setnoblockgetch(); #endif while (g_pSvrLink->LinkOK()) { #ifdef WIN32 switch (mygetch()) { case '?': case 'h': case 'H': printf("\nCommand List:\n"); printf("\t ? or h: display this Help informations!\n"); printf("\t x: To eXit this business unit.\n"); printf("\t d: Display functions status.\n"); printf("\t l: List functions status into <function.lst>.\n"); printf("Enter command to select:"); break; case 'x': case 'X': g_pSvrLink->bExit = true; continue; break; case 'd': case 'D': ListBPFunctions(NULL); break; case 'l': case 'L': ListBPFunctions("function.lst"); break; } #endif g_pSvrLink->Processing(&g_BUnit); if (g_pSvrLink->bExit) break; } g_pSvrLink->Close(); DEBUG_RUNTIME_MSGOUT("业务处理单元BU系统正常退出!\n"); g_LogFile.Close(); if (g_ini_para.dynamic_load_flag) { g_LoadDll.UnLoadAllDll(); g_desdll.UnLoadAllDll(); } ::CoUninitialize(); return(0); }
int CSvrLink::CallBPFunction(MSGBUF *pmb) { AP_REQUEST *preq; ST_CPACK rpack={0}; /* ****** Updated by CHENYH at 2006-3-23 0:37:37 ****** 为了能够为具体业务处理模块留出足够的堆栈空间,因此这里采用动态分配空间方式分配 ST_PACK pArrays[MAXROW]={0}; // 819200 / 在VC下缺省的stack空间本来也就1M (1048576) *******************************************************/ ST_PACK *pArrays; int recs; int rtn; char szMsg[256]; char *rdata = pmb->data+sizeof(AP_REQUEST); int rdlen = pmb->head.len-sizeof(AP_REQUEST); preq = (AP_REQUEST *)(pmb->data); ruserid.SourceNo = ntohs(preq->SourceNo); memcpy(&(ruserid.syshead),&(preq->syshead),sizeof(ruserid.syshead)); if (pProcess!=NULL) { if (DecodeHead((unsigned char *)rdata,rdlen,&head,szMsg)==sizeof(ST_PACKHEAD)) { memcpy(&reqhead,&head,sizeof(ST_PACKHEAD)); iLastReqType = head.RequestType; iAnswerMode = iDefaultAnswerMode; eMsg[0]='\0'; iLastRetCode = 0; rtn = (*pProcess)(&ruserid,rdata,rdlen,&iLastRetCode,eMsg); DataDone(iLastRetCode,eMsg); return(rtn); } } // 2006-3-23 0:56:40 采用动态分配,以少占用堆栈空间 pArrays = (ST_PACK *)malloc(((CXPack *)GetDefaultXPack())->GetPackLength()*MAXROW); if (DecodeBufWithArray((unsigned char *)rdata,rdlen,&rpack,pArrays,&recs,szMsg)>0) { int fno; ASSERT(rpack.head.firstflag==1); // 只有首包提交下来的。。。。 memcpy(&reqhead,&(rpack.head),sizeof(ST_PACKHEAD)); // 将请求包头记录下来 2005-9-21 17:35:06 memcpy(&head,&(rpack.head),sizeof(head)); memset(head.ParmBits,0,sizeof(head.ParmBits)); // 将结果集位图清空 head.recCount = 0; // Reset the recCount iLastReqType = rpack.head.RequestType; iAnswerMode = iDefaultAnswerMode; eMsg[0]='\0'; iLastRetCode = 0; fno = FindBPFunction(rpack.head.RequestType); if (fno>=0 && g_BDefines[fno].pFunc!=NULL) { unsigned int t1=GetTickCount(); // OK,have found the process function: #ifdef TESTINFO sprintf(szMsg,"Begin to call REQ%u <%s>!", rpack.head.RequestType, g_BDefines[fno].szRTName); DEBUG_RUNTIME_MSGOUT(szMsg); #endif rtn = (*pCallBDFunc)(fno,&ruserid,&rpack,pArrays,&iLastRetCode,eMsg); // 如果需要统计功能处理能力,在这里加上。。。 t1 = tc2_tc1(GetTickCount(),t1); DataDone(iLastRetCode,eMsg); if (iLastRetCode==0) { g_BDefines[fno].nSuccess++; g_BDefines[fno].dTakentime += t1; if (g_BDefines[fno].nSuccess==1) { g_BDefines[fno].nTt_max = g_BDefines[fno].nTt_min = t1; } else { if (g_BDefines[fno].nTt_max<t1) g_BDefines[fno].nTt_max=t1; if (g_BDefines[fno].nTt_min>t1) g_BDefines[fno].nTt_min = t1; } } else g_BDefines[fno].nFail++; //return(rtn); } else { iLastReqType = 0; iLastRetCode = 0; sprintf(szMsg,"BCC提交的请求<%u>在本业务单元中没有对应的处理定义!", rpack.head.RequestType); DEBUG_RUNTIME_MSGOUT(szMsg); rtn = -2; } } else { DEBUG_RUNTIME_MSGOUT(szMsg); rtn = -1; } free(pArrays); return(rtn); }
int CSvrLink::CallBPFunction(MSGBUF *pmb) { AP_REQUEST *preq; ST_CPACK rpack; // 20040409: QBIN希望能够处理多记录的请求 ST_PACK pArrays[MAXROW]; int recs; char szMsg[256]; preq = (AP_REQUEST *)(pmb->data); ruserid.SourceNo = ntohs(preq->SourceNo); memcpy(&(ruserid.syshead),&(preq->syshead),sizeof(ruserid.syshead)); //memcpy(&head,pmb->data+sizeof(AP_REQUEST),sizeof(head)); // 将原始请求的头截获下来,字序按照实际打包字序格式 // 这里留个底,也就不用转换字序了 if (DecodeBufWithArray((unsigned char *)(pmb->data+sizeof(AP_REQUEST)), pmb->head.len-sizeof(AP_REQUEST), &rpack,pArrays,&recs,szMsg)) { int fno; ASSERT(rpack.head.firstflag==1); // 只有首包提交下来的。。。。 fno = FindBPFunction(rpack.head.RequestType); if (fno>=0 && g_BDefines[fno].pFunc!=NULL) { int rtn; unsigned int t1=GetTickCount(); memcpy(&head,&(rpack.head),sizeof(head)); memset(head.ParmBits,0,sizeof(head.ParmBits)); // 将结果集位图清空 head.recCount = 0; // Reset the recCount iLastReqType = rpack.head.RequestType; iAnswerMode = iDefaultAnswerMode; // OK,have found the process function: #ifdef TESTINFO sprintf(szMsg,"Begin to call req%u <%s>!", rpack.head.RequestType, g_BDefines[fno].szRTName); DEBUG_RUNTIME_MSGOUT(szMsg); #endif eMsg[0]='\0'; iLastRetCode = 0; /* ****** Updated by CHENYH at 2004-2-21 12:23:30 ****** rtn = g_BDefines[fno].pFunc( &ruserid, &(rpack.pack), &retcode, szMsg ); */ rtn = CallBDFunc(fno,&ruserid,&rpack,pArrays,&iLastRetCode,eMsg); // 如果需要统计功能处理能力,在这里加上。。。 t1 = tc2_tc1(GetTickCount(),t1); DataDone(iLastRetCode,eMsg); if (iLastRetCode==0) { g_BDefines[fno].nSuccess++; g_BDefines[fno].dTakentime += t1; if (g_BDefines[fno].nSuccess==1) { g_BDefines[fno].nTt_max = g_BDefines[fno].nTt_min = t1; } else { if (g_BDefines[fno].nTt_max<t1) g_BDefines[fno].nTt_max=t1; if (g_BDefines[fno].nTt_min>t1) g_BDefines[fno].nTt_min = t1; } } else g_BDefines[fno].nFail++; return(rtn); } else { iLastReqType = 0; iLastRetCode = 0; sprintf(szMsg,"BCC提交的请求<%u>在本业务单元中没有对应的处理定义!", rpack.head.RequestType); DEBUG_RUNTIME_MSGOUT(szMsg); return(-2); } } else { DEBUG_RUNTIME_MSGOUT(szMsg); return(-1); } }