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

📄 dnsender.cpp

📁 SMS gateway. SMS protocol for CHINA mobile, unicom, lingtong. Using mysql to exchange message.
💻 CPP
字号:
/**********************************************************************
  FileName            : DnSender.cpp
  Description         : 下节点发送(线程)模块
  Version             : 1.0
  Date                : 2003年9月18日
  Author              : 刘荣辉
  Other               : 
***********************************************************************/

#include "GateWay.h"

int CGateWay::DnSender(void * pDnNode)
{
  char sSysEvent[SYS_EVENT_LEN];	//记录系统事件的字符串
  SendQUnit  SUnit;
  int PackLen;
  int iSent;
  //int SendFail;
  time_t nowtime;
  char timebuf[16];
  CDnNode *DnNode;

  DnNode=(CDnNode *)pDnNode;
  DnNode->SendThr = pthread_self();
  pthread_detach(DnNode->SendThr);
  sprintf(sSysEvent,"LOG: DnSender[%d] of DnNode[%s] is started.",(int)DnNode->SendThr,DnNode->ServiceCode);
  WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);    //写系统日志

  //sleep(1000);goto DnSenderEnd;

  while(1)	//不断从发送队列中取出数据包进行发送
  { 
		//DnNode->SendQ->Wait_Get(SUnit);	//阻塞等待获取发送队列单元
		if(DnNode->SendQ->Get(SUnit)==false)	//发现队列为空
		{
			if(DnNode->State)	//连接已断则退出发送线程
			{
				DnNode->State=2;
				break;
			}
			usleep(SendQ_Empty_Wait);
			continue;
		}
		CMPP_Deliver * tReqPack = (CMPP_Deliver *)SUnit.Pack;
		#ifdef DEBUG
		WrSystemLog->getTime(timebuf);
		if(ntohl(tReqPack->Head.Command_Id) == CMPP_DELIVER)
		{
			printf("\n================正向[%s]发CMPP_Deliver包==================\n",DnNode->ServiceCode);
			printf("发送时间:%s\n用户手机号:%s\n源号码:%s\n短信内容:%s",timebuf,tReqPack->Src_terminal_Id,tReqPack->Dest_Id,tReqPack->Deliver_Msg.Msg_Content);
		}
		else if(ntohl(tReqPack->Head.Command_Id) == CMPP_SUBMIT_RESP)
		{
			//printf("\n [%s]DnSender[%s]: Sending a Submit_Rsp pack. \n",timebuf,DnNode->ServiceCode);
		}
		else if(ntohl(tReqPack->Head.Command_Id) == CMPP_ACTIVE_TEST)
		{
			//printf("\n [%s]DnSender[%s]: Sending an Active_Test pack. \n",timebuf,DnNode->ServiceCode);
		}
		else if(ntohl(tReqPack->Head.Command_Id) == CMPP_ACTIVE_TEST_RESP)
		{
			printf("\n [%s]DnSender[%s]: Sending an Active_Test_Rsp pack. \n",timebuf,DnNode->ServiceCode);
		}
		else
		{
			printf("\n [%s]DnSender[%s]:  Got an unexpected pack[%d].\n",timebuf,DnNode->ServiceCode,ntohl(tReqPack->Head.Command_Id));
		}
		#endif
		
		//--------------------发送数据包---------------------
		//SendFail = 0;
		PackLen = ntohl(*(int *)SUnit.Pack);
		if(DnNode->State)	//连接已断
		{
			DnNode->SendQ->Put(SUnit);	//放回发送队列以便备份数据
			break;
		}
		iSent = DnNode->TcpSock.Writen(SUnit.Pack, PackLen);	//发送数据包
		if(iSent!=PackLen)	//发送失败,连接异常
    	{
			#ifdef DEBUG
			//printf("\n DnSender: PackLen=[%d],iSent=[%d].\n",PackLen,iSent);
			#endif
           	//SendFail = 1;	//连接异常,发送线程退出
			if(DnNode->State==0)
			{
				if(!DnNode->ToExit)
					DnNode->TcpSock.Close_sock();
				DnNode->State = 2;
			}

			FD_CLR(DnNode->TcpSock.sock, &DnSockSet);	//从套接字集中清除
			if(DnNode->TcpSock.sock == MaxSock)	//若最大的套接字失效
				MaxSock--;
			//从Socket_CP映射表中删除
			int DelNum = Sock_CP_Map.Delete(DnNode->TcpSock.sock);
			if(DelNum!=1)
			{
				sprintf(sSysEvent,"Warning: [%d] Sock_CP pair for DnNode[%s] is deleted!",DelNum,DnNode->ServiceCode);
				WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
			}

			DnNode->SendQ->Put(SUnit);	//放回发送队列以便重发或备份数据
			if(!UpNode->ToExit)
			{
				sprintf(sSysEvent,"Error[%d]: Connection with DnNode[%s] lost! DnSender exit!",iSent,DnNode->ServiceCode);
				WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);
			}
			break;
    	}
    	//else printf("\n=====================发送成功=======================\n");

		//-------------------放进已发送队列/删包----------------------
		unsigned int PackSeq=ntohl(*(unsigned int *)(SUnit.Pack + 8));
		#ifdef DEBUG
		//printf("\n DnSender: Sequence=[%d],iResent=[%d],SendFail=[%d] \n",PackSeq,SUnit.iResent,SendFail);
    	#endif
		//if( (SUnit.iResent>0) || SendFail)	//需要等应答或者发送失败,则放进已发送队列
		if(SUnit.iResent>0)	//需要等应答或者发送失败,则放进已发送队列
    	{
    		/*if(DnNode->ToExit)
			{
				DnNode->SendQ->Put(SUnit);	//放回发送队列以便备份数据
				break;
			}
			else
			{*/
				//修改队列单元标识
				time(&nowtime);
				SUnit.SendTime = nowtime + CMPP_SEND_TIMEOUT;	//下一次发送时间(重发时间)
				if(SUnit.iResent>0)
				{
					SUnit.iResent--;
					//放入已发送队列,(流水号--队列单元指针,映射哈希表)
					DnNode->SentQ.Add(PackSeq , SUnit);
					#ifdef DEBUG
					//printf("\n DnSender: A pack[%d = %x] is added to SentQ after sending! \n", PackSeq, PackSeq);
					#endif
				}
			//}
		}
		//else if( SUnit.iResent==-1 && SendFail==0)	//对于成功发送的应答包
		else if(SUnit.iResent==-1)	//对于成功发送的应答包
		{
			#ifdef DEBUG
			//printf("\n DnSender: A CMPP_Rsp pack[%x] is delete after sent successfully! \n", PackSeq);
			#endif
			free(SUnit.Pack);	//删除包,释放内存
		}

    	if(DnNode->State)	//连接已断
    		break;	//发送线程退出
  }//while(1)
  
//DnSenderEnd:
  DnNode->SendThr = 0;
  if(DnNode->ToExit)
	sprintf(sSysEvent,"LOG: DnSender of DnNode[%s] is ended! ",DnNode->ServiceCode);
  else
	sprintf(sSysEvent,"Error: DnSender of DnNode[%s] QUIT! ",DnNode->ServiceCode);
  WrSystemLog->WriteLog(sSysEvent,SYSTEMLOG);

  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -