⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnnodelogin.cpp.bak

📁 SMS gateway. SMS protocol for CHINA mobile, unicom, lingtong. Using mysql to exchange message.
💻 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 + -