📄 dnnodelogin.cpp.bak
字号:
/**********************************************************************
FileName : DnNodeLogin.cpp
Description : 下端登录验证线程模块
Version : 1.0
Date : 2003年9月11日
Author : 刘荣辉
Other : 收Login,应答,下节点初始化,加入收发套接字集
***********************************************************************/
#include "GateWay.h"
#include "DnNode.h"
void * CGateWay::DnNodeLogin(void * pThrParam)
{
int RetCode, PackTag;
char sSysEvent[SYS_EVENT_LEN];
int Num;
CGateWay *Gateway;
CDnNode * NewDnNode;
CMPP_Connect MyLogin;
void **pRspPack; //Login_Rsp包指针的指针
char *RspPack; //Login_Rsp包指针
ThreadParam3 *ThrParam;
ThrParam=(ThreadParam3 *)pThrParam;
Gateway=(CGateWay *)ThrParam->MyPointer;
TCPsocket TheSock;
TheSock.sock = ThrParam->MyInt;
sprintf(sSysEvent,"LOG: DnNodeLogin is waiting for Login_Req...");
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG); //写系统日志
//接收CMPP_Connect包
RetCode = TheSock.RecvPack2(&MyLogin, sizeof(CMPP_Connect));
if(RetCode)
{
sprintf(sSysEvent,"Error[%d]: Failed in RecvPack2(CMPP_Connect),Connection is Cut!",RetCode);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
close(ThrParam->MyInt);
free(ThrParam); //释放线程参数所占内存,在DnListener()中malloc
return (void *)NULL; //退出登录验证模块
}
#ifdef DEBUG
printf("\n DnNodeLogin: Got a Login_Req!\n");
#endif
//检查下节点是否已经连接
char SrcAddr[10];
memcpy(SrcAddr, MyLogin.Source_Addr, sizeof(MyLogin.Source_Addr));
SrcAddr[sizeof(MyLogin.Source_Addr)] = '\0';
NewDnNode=NULL;
NewDnNode = (CDnNode *) Gateway->Code_CP_Map.Find(atoi(SrcAddr));
if(NewDnNode!=NULL && NewDnNode->State==0) //拒绝已连接的下节点重复连接
{
sprintf(sSysEvent,"Warning: Reduplicate Connection from DownNode[%s] is denied!", Gateway->CP_Array[Num].ServiceCode);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
close(ThrParam->MyInt);
free(ThrParam); //释放线程参数所占内存,在DnListener()中malloc
return (void *)NULL; //退出登录验证模块
}
if(NewDnNode==NULL) //内存映射表中没有此服务代码(上节点未曾登录过)
{
char tmpCode[11];
strncpy(tmpCode,MyLogin.Source_Addr,sizeof(MyLogin.Source_Addr));
for(Num=0; Num < Gateway->DnNodeNum; Num++)
{
if(strncmp(Gateway->CP_Array[Num].ServiceCode , tmpCode, sizeof(MyLogin.Source_Addr))==0 && strcmp(Gateway->CP_Array[Num].NodeIp , (char *)inet_ntoa(ThrParam->ClientIp.sin_addr))==0)
break;
}
if(Num==Gateway->DnNodeNum) //服务代码与绑定的IP不匹配
{
sprintf(sSysEvent,"Warning: ServiceCode[%s] and Client's IP[%s] doesn't match! Connection is denied!",tmpCode,(char *)inet_ntoa(ThrParam->ClientIp.sin_addr));
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
close(ThrParam->MyInt);
free(ThrParam); //释放线程参数所占内存,在DnListener()中malloc
return (void *)NULL; //退出登录验证模块
}
//DnNode对象的构造,赋值
NewDnNode = new CDnNode;
NewDnNode->Num = Num; //在下节点信息结构体数组(常驻内存)中的下标
strcpy(NewDnNode->ServiceCode , Gateway->CP_Array[Num].ServiceCode);
NewDnNode->NodeID = atoi(NewDnNode->ServiceCode); //下节点的节点编号
strcpy(NewDnNode->ServiceID , Gateway->CP_Array[Num].ServiceID);
strcpy(NewDnNode->ServiceName , Gateway->CP_Array[Num].ServiceName);
NewDnNode->CPID = Gateway->CP_Array[Num].CPID;
NewDnNode->InterfaceType = Gateway->CP_Array[Num].InterfaceType;
strcpy(NewDnNode->MOTable , Gateway->CP_Array[Num].MOTable);
strcpy(NewDnNode->NodeIp , Gateway->CP_Array[Num].NodeIp);
strcpy(NewDnNode->Username , Gateway->CP_Array[Num].Username);
strcpy(NewDnNode->Secret , Gateway->CP_Array[Num].Secret);
NewDnNode->WantReport = Gateway->CP_Array[Num].WantReport;
NewDnNode->TestTime = Gateway->CP_Array[Num].TestTime;
NewDnNode->RecvQ_Size = Gateway->CP_Array[Num].RecvQ_Size;
NewDnNode->SendQ_Size = Gateway->CP_Array[Num].SendQ_Size;
NewDnNode->SentW_Size = Gateway->CP_Array[Num].SentW_Size;
strcpy(NewDnNode->FeeType , Gateway->CP_Array[Num].FeeType);
strcpy(NewDnNode->FeeCode , Gateway->CP_Array[Num].FeeCode);
NewDnNode->Encoding = Gateway->CP_Array[Num].Encoding;
NewDnNode->ShowLog = Gateway->CP_Array[Num].ShowLog;
strcpy(NewDnNode->Seperator , Gateway->CP_Array[Num].Seperator);
strcpy(NewDnNode->URL , Gateway->CP_Array[Num].URL);
NewDnNode->State = 1;
#ifdef DEBUG
printf("\n DnNodeLogin: The DnNode[%d] is NOT in Code_CP_Map, adding... \n",NewDnNode->NodeID);
#endif
//建立Code_下节点对象指针映射,一旦建立便不再删除,即使连接断开
Gateway->Code_CP_Map.Add(NewDnNode->NodeID , (char *)NewDnNode);
}
//设置等待CMPP_Connect(Login)包的最大时间(2秒)??????????
//CMPP_Connect包的应答包构造
pRspPack = (void **)malloc(sizeof(char **)); //应答包构造模块需返回的应答包指针的指针
PackTag = NewDnNode->MakeRspPack(&MyLogin, pRspPack);
RspPack = (char *)*pRspPack;
if(PackTag) //收到的包错误或者验证失败
{
sprintf(sSysEvent,"Error[%d]: DownNode[%s] Login Failed!",PackTag,NewDnNode->ServiceCode);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
close(ThrParam->MyInt);
free(ThrParam); //释放线程参数所占内存,在DnListener()中malloc
free(RspPack); //在CDnNode::MakeRspPack()中malloc
free(pRspPack); //应答包的指针所占内存
return (void *)NULL; //退出登录验证模块
}
if(Gateway->ToExit)
{
close(ThrParam->MyInt);
free(ThrParam); //释放线程参数所占内存,在DnListener()中malloc
free(RspPack); //在CDnNode::MakeRspPack()中malloc
free(pRspPack); //应答包的指针所占内存
return (void *)NULL; //退出登录验证模块
}
//发送CMPP_Connect_Resp包
RetCode = TheSock.Writen(RspPack,sizeof(CMPP_Connect_Resp));
free(RspPack); //在CDnNode::MakeRspPack()中malloc
free(pRspPack); //应答包的指针所占内存
if(RetCode != sizeof(CMPP_Connect_Resp))
{
sprintf(sSysEvent,"Error[%d]: Sending CMPP_Connect_Resp to DownNode[%s] Failed!",RetCode,NewDnNode->ServiceCode);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
close(ThrParam->MyInt);
free(ThrParam); //释放线程参数所占内存
return (void *)NULL; //退出登录验证模块
}
printf("\n DnNodeLogin =========5========= \n");
NewDnNode->NodeInit(); //Login成功,初始化DnNode对象
printf("\n DnNodeLogin ==========6======== \n");
NewDnNode->TcpSock.sock = TheSock.sock;
NewDnNode->State = 0; //状态为连接正常
NewDnNode->WrSystemLog = Gateway->WrSystemLog;
//把DnNode对象指针插入哈希映射表
Gateway->Sock_CP_Map.Add(NewDnNode->TcpSock.sock , (char *)NewDnNode); //建立Socket_下节点对象指针映射
printf("\n DnNodeLogin =========8========= \n");
//修改下端连接套接字集
pthread_mutex_lock(&Gateway->SockSetLock);
FD_SET(NewDnNode->TcpSock.sock, &Gateway->DnSockSet);
if (NewDnNode->TcpSock.sock > Gateway->MaxSock)
{
Gateway->MaxSock = NewDnNode->TcpSock.sock;
}
pthread_mutex_unlock(&Gateway->SockSetLock);
sprintf(sSysEvent,"LOG: DownNode[%s] Logined Successfully! Socket=[%d]",NewDnNode->ServiceCode,NewDnNode->TcpSock.sock);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
free(ThrParam); //释放线程参数所占内存
int GotNum=0;
char FileName[100];
//---------从备份文件中导入接收队列数据---------
FileOpr *RecvQFile = new FileOpr(); //用于从备份文件中获取队列数据的操作对象
memset(FileName,0,sizeof(FileName));
sprintf(FileName,"%s%s%s",Gateway->DnQueueBak,NewDnNode->ServiceCode,Gateway->DnRecvQ_File);
RecvQUnit * RUnit = RecvQFile->RecvQ_Restore(FileName,&GotNum); //在函数中打开关闭文件,malloc空间
if (RUnit!=NULL) //成功从备份文件中获取到队列数据
{
for(int i=0;i<GotNum;i++)
{
RecvQUnit * pRUnit = (RecvQUnit *)( RUnit + i*sizeof(RecvQUnit));
//printf("\n DnNodeLogin: RecvQUnit: packtype=%x, Sequence=[%x].packlen=%d. \n", ntohl(*(unsigned int *)(pRUnit->Pack+4)), ntohl(*(unsigned int *)(pRUnit->Pack+8)), ntohl(*(unsigned int *)pRUnit->Pack));
NewDnNode->RecvQ->Wait_Put(*pRUnit);
}
free(RUnit);
}
//else 没有从文件中读到数据,可能文件不存在或为空或者文件打开失败
delete RecvQFile;
sprintf(sSysEvent,"LOG: Got [%d] RecvQ Units from File[%s].",GotNum, FileName);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
//=========== debug =========
//RecvQUnit ReqUnit;
//NewDnNode->RecvQ->Get(ReqUnit);
//printf("\n DnNodeLogin: Loaded a CMPP pack[%x], Sequence=[%x]. Packlen=%d.\n",ntohl(*(int *)(ReqUnit.Pack+4)),ntohl(*(int *)(ReqUnit.Pack+8)),ntohl(*(int *)ReqUnit.Pack));
//NewDnNode->RecvQ->Put(ReqUnit);
//====================
//---------从备份文件中导入发送队列数据---------
FileOpr *SendQFile = new FileOpr(); //用于从备份文件中获取队列数据的操作对象
memset(FileName,0,sizeof(FileName));
sprintf(FileName,"%s%s%s",Gateway->DnQueueBak,NewDnNode->ServiceCode,Gateway->DnSendQ_File);
SendQUnit * SUnit = SendQFile->SendQ_Restore(FileName,&GotNum); //在函数中打开关闭文件,malloc空间
if (SUnit!=NULL) //成功从备份文件中获取到队列数据
{
for(int i=0;i<GotNum;i++)
{
SendQUnit * pSUnit = (SendQUnit *)( SUnit + i*sizeof(SendQUnit));
*(int *)(pSUnit->Pack+8) = htonl(NewDnNode->GetSequence()); //修改包流水号
//printf("\n DnNodeLogin: SendQUnit: packlen=%d, packtype=%x, SrcNode=%d. \n", ntohl(*(unsigned int *)pSUnit->Pack), ntohl(*(unsigned int *)(pSUnit->Pack+4)), pSUnit->SrcNode);
NewDnNode->SendQ->Wait_Put(*pSUnit);
}
free(SUnit);
}
//else 没有从文件中读到数据,可能文件不存在或为空或者文件打开失败
delete SendQFile;
sprintf(sSysEvent,"LOG: Got [%d] SendQ Units from File[%s].",GotNum, FileName);
Gateway->WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
//---------下节点发送线程模块---------
Gateway->DnSender(NewDnNode);
//if(Gateway->ToExit) {}
return (void *)NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -