// Cmpp3.cpp: implementation of the CCmpp3 class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Cmpp3.h" //#include "MCmpp3.h" /* #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif */ ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// #include #include #include "..\..\..\public\md53\\md5_L.h" CCmpp3::CCmpp3() { m_hSocket = INVALID_SOCKET; memset( m_szIP , 0 , sizeof(m_szIP) ); m_lPort = 0; m_bQuitThread = false; m_dwEndSendTime = 0; m_dwEndRecvTime = 0; m_dwTestCount = 0; m_bRecvFrame = false; m_lID = 1; m_lID_Begin = 0; m_pRecvProc = NULL; m_bConnect = false; m_bLoginCmpp3= -1; m_bInitCmpp3 = false; memset(m_szCmpp3IP ,0,sizeof(m_szCmpp3IP)); memset(m_szCmpp3User ,0,sizeof(m_szCmpp3User)); memset(m_szCmpp3Passwd,0,sizeof(m_szCmpp3Passwd)); memset(m_szCmpp3CorpID,0,sizeof(m_szCmpp3CorpID)); WSADATA wsaData; //用于初始化socket的结构 //以下为初始化SOCKET环境 int iTemp=WSAStartup(0x0101,&wsaData); //初始化socket环境 InitializeCriticalSection(&m_CriSendSms); InitializeCriticalSection(&m_CriRespList); InitializeCriticalSection(&m_CriDeliverList); InitializeCriticalSection(&m_CriStatusList); InitializeCriticalSection(&m_CriCmpp3ExchangeResp); InitializeCriticalSection(&m_CriErrMsg); InitializeCriticalSection(&m_CriSendFrame); //定义队列 m_lSendID = 1; m_pSendList = new Cmpp3_Send_List[CMPP3_SMS_MAX_LIST]; m_pRespList = new Cmpp3_Send_Resp[CMPP3_SMS_MAX_RESP]; m_pDeliverList = new Cmpp3_Deliver_List[CMPP3_SMS_MAX_DELIVER]; m_pStatusList = new Cmpp3_Deliver_List[CMPP3_SMS_MAX_STATUS]; m_pCmpp3ExchangeResp = new Cmpp3ExchangeResp[CMPP3_SMS_MAX_CMPP3EXCHANGERESP]; memset(m_pSendList,0,sizeof(Cmpp3_Send_List)* CMPP3_SMS_MAX_LIST); memset(m_pRespList,0,sizeof(Cmpp3_Send_Resp)* CMPP3_SMS_MAX_RESP); memset(m_pDeliverList,0,sizeof(Cmpp3_Deliver_List)* CMPP3_SMS_MAX_DELIVER); memset(m_pStatusList,0,sizeof(Cmpp3_Deliver_List) * CMPP3_SMS_MAX_STATUS); memset(m_pCmpp3ExchangeResp,0,sizeof(Cmpp3ExchangeResp)* CMPP3_SMS_MAX_CMPP3EXCHANGERESP); m_lSendList = 0; m_lRespList = 0; m_lDeliverList=0; m_lStatusList=0; m_lCmpp3ExchangeRespList=0; m_pCmppExchange = NULL; m_lCmppExchange = 0; m_bAdc = false; m_dwEndSocketSendTime = 0; m_lSendInterval = 0; m_lSendIntervalCount = 1; m_lSendIntervalIndex = 0; m_hThread = INVALID_HANDLE_VALUE; m_hThread_Send = INVALID_HANDLE_VALUE; } CCmpp3::~CCmpp3() { Stop(); //删除数据 if ( m_pSendList ) {delete m_pSendList;m_pSendList=NULL;} if ( m_pRespList ) {delete m_pRespList;m_pRespList=NULL;} if ( m_pDeliverList ) {delete m_pDeliverList;m_pDeliverList=NULL;} if ( m_pStatusList ) {delete m_pStatusList;m_pStatusList=NULL;} if ( m_pCmpp3ExchangeResp ) {delete m_pCmpp3ExchangeResp;m_pCmpp3ExchangeResp=NULL;} DeleteCriticalSection(&m_CriSendSms); DeleteCriticalSection(&m_CriRespList); DeleteCriticalSection(&m_CriDeliverList); DeleteCriticalSection(&m_CriStatusList); DeleteCriticalSection(&m_CriCmpp3ExchangeResp); DeleteCriticalSection(&m_CriErrMsg); DeleteCriticalSection(&m_CriSendFrame); //退出Socket WSACleanup(); } BOOL CCmpp3::Connect(const char *pAddr, long lPort, BOOL bReConnect) { if ( !bReConnect && m_hSocket!=INVALID_SOCKET) //已连接,并且无需重连 { return true; } this->Stop(); //重新连接,先让原来的线程停止 strcpy( m_szIP,pAddr ); m_lPort = lPort; sockaddr_in sAddr; m_hSocket=socket(AF_INET,SOCK_STREAM,0); sAddr.sin_family=AF_INET; sAddr.sin_port=0; sAddr.sin_addr.s_addr=htonl(INADDR_ANY); if (bind(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR) { return false; } sAddr.sin_port=htons((unsigned short)lPort); sAddr.sin_addr.s_addr=inet_addr(pAddr); if (sAddr.sin_addr.s_addr == INADDR_NONE) { LPHOSTENT lphost; lphost = gethostbyname(pAddr); if (lphost != NULL) sAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr; else { Close(); return false; } } if (connect(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR) { Close(); return false; } //设置Socket u_long ulTemp=1; //将SOCKET设成非阻塞式的SOCKET //u_long ulTemp=0; //将SOCKET设成阻塞式的SOCKET ioctlsocket( m_hSocket,FIONBIO,&ulTemp ); ulTemp=1024000; setsockopt( m_hSocket , SOL_SOCKET, SO_SNDBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲 ulTemp=1024000; setsockopt( m_hSocket , SOL_SOCKET, SO_RCVBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲 m_bQuitThread = false; DWORD dwTemp; m_hThread=CreateThread(NULL,0,SocketRecv,(LPVOID)this,0,&dwTemp); // if ( !::AfxBeginThread((AFX_THREADPROC)CNetSocket::SocketRecv,(LPVOID)this,THREAD_PRIORITY_LOWEST) ) if ( m_hThread == INVALID_HANDLE_VALUE ) { Close(); return false; } m_hThread_Send=CreateThread(NULL,0,SocketSend,(LPVOID)this,0,&dwTemp); // if ( !::AfxBeginThread((AFX_THREADPROC)CNetSocket::SocketRecv,(LPVOID)this,THREAD_PRIORITY_LOWEST) ) if ( m_hThread_Send == INVALID_HANDLE_VALUE ) { Close(); return false; } //SetThreadPriority(m_hThread,THREAD_PRIORITY_LOWEST); //设置优先级 m_bConnect = true; return true; } BOOL CCmpp3::Connect2() { sockaddr_in sAddr; m_hSocket=socket(AF_INET,SOCK_STREAM,0); sAddr.sin_family=AF_INET; sAddr.sin_port=0; sAddr.sin_addr.s_addr=htonl(INADDR_ANY); if (bind(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR) { return false; } sAddr.sin_port=htons((unsigned short)m_lPort); sAddr.sin_addr.s_addr=inet_addr(m_szIP); if (sAddr.sin_addr.s_addr == INADDR_NONE) { LPHOSTENT lphost; lphost = gethostbyname(m_szIP); if (lphost != NULL) sAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr; else { Close(); return false; } } if (connect(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR) { Close(); return false; } //设置Socket u_long ulTemp=1; //将SOCKET设成非阻塞式的SOCKET //u_long ulTemp=0; //将SOCKET设成阻塞式的SOCKET ioctlsocket( m_hSocket,FIONBIO,&ulTemp ); ulTemp=1024000; setsockopt( m_hSocket , SOL_SOCKET, SO_SNDBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲 ulTemp=1024000; setsockopt( m_hSocket , SOL_SOCKET, SO_RCVBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲 return true; } BOOL CCmpp3::isConnect() { return m_bConnect; } void CCmpp3::Stop() { m_bQuitThread = true; if (m_hThread != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread,2000) == WAIT_TIMEOUT ) //等待5秒,让线程退出 { TerminateThread(m_hThread,0); //如果退出超时,强制结束线程 } m_hThread = INVALID_HANDLE_VALUE; if (m_hThread_Send != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread_Send,2000) == WAIT_TIMEOUT ) //等待5秒,让线程退出 { TerminateThread(m_hThread_Send,0); //如果退出超时,强制结束线程 } m_hThread_Send = INVALID_HANDLE_VALUE; Close(); } BOOL CCmpp3::isSocketClose(SOCKET s) { BOOL bConnDropped = FALSE; INT iRet = 0; BOOL bOK = TRUE; if (s == INVALID_SOCKET) return TRUE; struct timeval timeout = { 0, 0 }; fd_set readSocketSet; FD_ZERO(&readSocketSet); FD_SET(s, &readSocketSet); iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout); bOK = (iRet > 0); if(bOK) { bOK = FD_ISSET(s, &readSocketSet); } if(bOK) { CHAR szBuffer[1] = ""; iRet = recv(s, szBuffer, 1, MSG_PEEK); bOK = (iRet > 0); if(!bOK) { INT iError = WSAGetLastError(); bConnDropped = (( iError == WSAENETRESET) || (iError == WSAECONNABORTED) || (iError == WSAECONNRESET) || (iError == WSAEINVAL) || (iRet == 0)); } } return(bConnDropped); } void CCmpp3::Close() { if ( m_hSocket == INVALID_SOCKET ) return; if ( m_hSocket != INVALID_SOCKET ) closesocket(m_hSocket); m_hSocket = INVALID_SOCKET; m_bConnect = false; //m_dwEndSendTime=0; //m_dwEndRecvTime=0; } long CCmpp3::Send(SOCKET sock,BYTE *pData, long lLen) { #define SOCKET_SEND_TIMEOUT 10000 //10秒发送超时 if ( sock == INVALID_SOCKET ) return 0; long lSended = 0; DWORD lTimeOut = ::GetTickCount(); while ( 1 ) { long lRet = send(sock,(char*)(pData+lSended), lLen-lSended,0); if ( lRet == SOCKET_ERROR ) //发送错误 { if ( GetLastError() != WSAEWOULDBLOCK ) //绶区已满 return SOCKET_ERROR; } if ( lRet > 0 ) { lSended += lRet; if ( lSended >= lLen ) break; } else { Sleep_Lu( 20 ); //绶冲区已满,稍等 } if ( ::GetTickCount() - lTimeOut > SOCKET_SEND_TIMEOUT ) break; } return lSended; } DWORD WINAPI CCmpp3::SocketSend(LPVOID lParam) { CCmpp3 * pNet = (CCmpp3 *)lParam; while ( !pNet->m_bQuitThread ) { //发送短信 long lCount = pNet->Back_Send(); if ( lCount>0 ) Sleep_Lu(1); else Sleep_Lu(15); } return 1; } DWORD WINAPI CCmpp3::SocketRecv(LPVOID lParam) { CCmpp3 * pNet = (CCmpp3 *)lParam; Cmpp3_Data_Recv Drecv={0}; pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间 DWORD dwEndSend=GetTickCount(); while ( !pNet->m_bQuitThread ) { BOOL bReConnect=false; if ( isSocketClose(pNet->m_hSocket) ) { pNet->Close(); //重新接收数据 if ( Drecv.pRecvFrame ) delete Drecv.pRecvFrame; memset(&Drecv,0,sizeof(Drecv)); if ( pNet->m_bInitCmpp3 ) //原已连接的,重新连接 { bReConnect = true; } else { pNet->m_bLoginCmpp3 = -4; //对端断开连接,登录失败 } } if ( ReadFrame(pNet->m_hSocket,&Drecv) ) //判断是否有接收到新的Frame { pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间 pNet->m_bRecvFrame = true; pNet->RecvFrame(Drecv); //处理接收到的帧 Drecv.lDataLen = 0; delete Drecv.pRecvFrame; Drecv.pRecvFrame = NULL; } //判断接收是否超时 //if ( pNet->m_dwEndSendTime > 0 && !pNet->m_bRecvFrame) if ( pNet->m_dwEndSendTime>0 && ::GetTickCount() - pNet->m_dwEndRecvTime >CMPP3_ACTIVE_TIMEOUT*2 ) //接收超时 { pNet->m_dwEndRecvTime = ::GetTickCount()-CMPP3_ACTIVE_TIMEOUT; //如果接收超时,重新计数 pNet->Close(); //重新接收数据 if ( Drecv.pRecvFrame ) delete Drecv.pRecvFrame; memset(&Drecv,0,sizeof(Drecv)); bReConnect = true; } //判断是否应该发送Active_Test指令 if ( pNet->m_dwEndSendTime > 0 ) { if ( ::GetTickCount() - pNet->m_dwEndSendTime > CMPP3_ACTIVE_TESTTIME ) //重新连接 { ULONG lSeq=0; pNet->SendFrame(pNet->m_hSocket,pNet->m_lID,pNet->m_dwEndSendTime, CMPP3_ACTIVE_TEST , NULL , 0 ,lSeq ); } } //发送短信 //pNet->Back_Send(); if ( bReConnect ) { for ( int i=0 ; i<30 && !pNet->m_bQuitThread; i++ ) //延时5秒 { Sleep_Lu(100); } pNet->SetErrMsg(_T("Cmpp3消息:正在重连网关...")); if ( !pNet->m_bQuitThread ) pNet->InitCmpp32(); //重新连接到服务器 } //Sleep_Lu(1); } if ( Drecv.pRecvFrame ) delete Drecv.pRecvFrame; pNet->Close(); return 1; } void CCmpp3::SetRecvProc(RECVPROC_Cmpp3 proc) { m_pRecvProc = proc; } BOOL CCmpp3::ReadFrame(SOCKET s, Cmpp3_Data_Recv *pRecv) { ULONG nBytes=0; ioctlsocket(s,FIONREAD, &nBytes); if (nBytes <= 0 ) { Sleep_Lu(1); //没有数据,等待一段时间 return false; } if ( pRecv->lDataLen <= 0 && nBytes<= sizeof(pRecv->lDataLen) ) //未收够长度信息 { Sleep_Lu(1); //没有数据,等待一段时间 return false; } long lRet; if (pRecv->lDataLen <= 0 ) //未收到数据,现在开始接收 { lRet = recv(s, (char*)&pRecv->lDataLen,sizeof(pRecv->lDataLen),0); if ( lRet > 0 ) { pRecv->lDataLen = ntohl(pRecv->lDataLen); if ( pRecv->lDataLen > 0 ) { if ( pRecv->pRecvFrame ) { delete pRecv->pRecvFrame; pRecv->pRecvFrame = NULL; } pRecv->pRecvFrame = new BYTE[pRecv->lDataLen]; *((long*)pRecv->pRecvFrame) = pRecv->lDataLen; //存好前4个字节 pRecv->lRecvLen = sizeof(pRecv->lDataLen); } } } else { //计算需要接收的总字节数 ULONG lBeRecv = pRecv->lDataLen-pRecv->lRecvLen; lRet = recv(s,(char*)pRecv->pRecvFrame+pRecv->lRecvLen , lBeRecv ,0); if ( lRet > 0 ) pRecv->lRecvLen += lRet ; if ( pRecv->lRecvLen == pRecv->lDataLen ) //Frame 已收满 { pRecv->lDataLen = 0; //重新开始接收 return true; } } return false; } BOOL CCmpp3::RecvFrame(Cmpp3_Data_Recv &Drecv) { Cmpp3_Head * pHead=(Cmpp3_Head *)Drecv.pRecvFrame; if ( pHead->Total_Length != Drecv.lRecvLen ) return false; pHead->Command_Id = ntohl(pHead->Command_Id); pHead->Sequence_Id= ntohl(pHead->Sequence_Id); BYTE * pData = (BYTE*)(Drecv.pRecvFrame+sizeof(Cmpp3_Head)); long lLen = pHead->Total_Length-sizeof(Cmpp3_Head); long lRet = 0; switch( pHead->Command_Id ) { case CMPP3_CONNECT_RESP: lRet = Process_Connect(*pHead,pData,lLen); break; case CMPP3_SUBMIT_RESP: lRet = Process_Submit(*pHead,pData,lLen); break; case CMPP3_ACTIVE_TEST: lRet = Process_Active(*pHead,pData,lLen); break; case CMPP3_DELIVER: lRet = Process_Deliver(*pHead,pData,lLen); break; default: break; } return lRet; } long CCmpp3::Cmpp3_Init(const char *pIP,long lPort, const char *pUser, const char *pPasswd,const char * pCorpID) { if ( !Connect(pIP,lPort) ) { return -1; //连接服务器失败 } //记录信息 strcpy(m_szCmpp3IP,pIP); strcpy(m_szCmpp3User,pUser); strcpy(m_szCmpp3Passwd,pPasswd); strcpy(m_szCmpp3CorpID,pCorpID); //生成Auth UCHAR Auth[64]={0}; long lAdd=0; strcpy((char*)Auth,pUser); lAdd += (long)strlen(pUser); lAdd += 9; strcpy((char*)(Auth+lAdd),pPasswd); lAdd += (long)strlen(pPasswd); char str[256]={0}; SYSTEMTIME t;GetLocalTime(&t); sprintf( str,"%02d%02d%02d%02d%02d",t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond); strcpy((char*)(Auth+lAdd),str); lAdd += (long)strlen(str); MD5_L md5; BYTE bMd5[64]={0}; //memcpy(bMd5 , md5.MD5Byte(Auth,lAdd),16); md5.MD5Byte(Auth, lAdd, bMd5); Cmpp3_Connect connect={0}; strcpy(connect.Source_Addr,pUser); //if ( atol(pUser)>=100000 && atol(pUser)<200000 ) //连接到短信易cmpp协议时,不用加密 //memcpy(connect.AuthenticatorSource,pPasswd,strlen(pPasswd)<16?strlen(pPasswd):16); if ( lPort == CMPP3_EXCHANGE_PORT || lPort == CMPP3_EXCHANGE_PORT2 ) //连接中转时,不用加密 ; else memcpy(connect.AuthenticatorSource,bMd5,16); connect.Version = 0x30; connect.Timestamp = atol(str); connect.Timestamp = htonl(connect.Timestamp); m_lID = 1; //包序号从1开始 if (strlen(pUser) == 1 && pUser[0] >= '0' && pUser[0] <= '9') //只有1位的用户名,认为是中转登录 { m_lID_Begin = atol(pUser) * 0xFFFFFFF; //序号以登录的端口号开始,用于中转时判断数据包 m_lID = m_lID + m_lID_Begin; } m_bLoginCmpp3 = -1; ULONG lSeq=0; if ( !SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_CONNECT,(UCHAR*)&connect,sizeof(connect),lSeq) ) { m_bQuitThread = true; return -2; //发送数据失败 } long lTime = ::GetTickCount(); while ( m_bLoginCmpp3 == -1 ) { if ( ::GetTickCount()-lTime > 30000 ) //超时了 break; Sleep_Lu(20); } if ( m_bLoginCmpp3==0 ) { m_bInitCmpp3 = true; //已初始化 return m_bLoginCmpp3; //返回成功 } if ( m_bLoginCmpp3 == -1 ) { m_bQuitThread = true; return -3; //登录超时 } else { m_bQuitThread = true; return m_bLoginCmpp3; //登录返回成功,具体请看错误码 } m_bQuitThread = true; return -4; //其它错误 } long CCmpp3::SendFrame(SOCKET sock,ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,UCHAR *pData, long lDataLen,ULONG & lSeq ) { //EnterCriticalSection(&m_CriSendFrame); //防止冲突 Cmpp3_Head head={0}; long lAllLen; head.Total_Length = sizeof(head)+lDataLen; lAllLen = head.Total_Length; head.Command_Id = lCommandID; if (lID & 0x0FFFFFFF >= 0xFFFFFF0)//高4位用于标识中转码号第三位,低28位为ID,当低28位的值超过0xFFFFFF0时,重新开始序号 { lID = (lID & 0xF0000000) + 1; } if ( lSeq > 0 ) head.Sequence_Id = lSeq; //直接使用相同序号的发送 else head.Sequence_Id = lID++; lSeq = head.Sequence_Id; //返回 head.Total_Length = htonl(head.Total_Length); head.Command_Id = htonl(head.Command_Id); head.Sequence_Id = htonl(head.Sequence_Id); dwEndSendTime = ::GetTickCount(); //记录最后发送时间 BYTE * pSData = new BYTE[lAllLen]; memcpy(pSData,&head,sizeof(head)); memcpy(pSData+sizeof(head),pData,lDataLen); BOOL bOK = Send(sock,(BYTE*)pSData , lAllLen ); delete pSData; long lRet = 0; if ( bOK ) lRet = head.Sequence_Id; //LeaveCriticalSection(&m_CriSendFrame); //防止冲突 return lRet; } long CCmpp3::Process_Connect(Cmpp3_Head head,BYTE *pData, long lLen) { Cmpp3_Connect_Resp * pResp = (Cmpp3_Connect_Resp *)pData; #ifdef CMPP3_3_0 pResp->Status = ntohl(pResp->Status); #endif if ( m_bInitCmpp3 && pResp->Status != 0 ) //需要重新登录 { //InitCmpp32(); //登录不成功,关闭连接 this->Close(); } CString str; str.Format(_T("Cmpp3消息:连接网关返回代码:%d") , pResp->Status ); SetErrMsg(str); m_bLoginCmpp3 = pResp->Status; return 1; } BOOL CCmpp3::SendSms(Cmpp3_Send_List sms) { for (int j = 0; j < 200; j++) { if (Sms_Add(sms)) return sms.lSendID; /* //从当前点到结尾 EnterCriticalSection(&m_CriSendSms); //防止冲突 for ( int i=0 ; i< SMS_MAX_LIST; i++ ) { if ( m_pSendList[i].lSendID == 0 ) //其等于0时,认为此位置为空 { sms.lSendTime = 0; sms.lReSendCount = 0; m_pSendList[i] = sms; LeaveCriticalSection(&m_CriSendSms); //防止冲突 return sms.lSendID; break; } } LeaveCriticalSection(&m_CriSendSms); //防止冲突 */ Sleep_Lu(20); //延时10秒 } return false; } BOOL CCmpp3::InitCmpp32() { m_bLoginCmpp3 = -1; if ( !Connect2() ) { return false; //连接服务器失败 } //生成Auth UCHAR Auth[64]={0}; long lAdd=0; strcpy((char*)Auth,m_szCmpp3User); lAdd += (long)strlen(m_szCmpp3User); lAdd += 9; strcpy((char*)(Auth+lAdd),m_szCmpp3Passwd); lAdd += (long)strlen(m_szCmpp3Passwd); char str[256]={0}; SYSTEMTIME t;GetLocalTime(&t); sprintf( str,"%02d%02d%02d%02d%02d",t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond); strcpy((char*)(Auth+lAdd),str); lAdd += (long)strlen(str); MD5_L md5; BYTE bMd5[64]={0}; //memcpy(bMd5 , md5.MD5Byte(Auth,lAdd),16); md5.MD5Byte(Auth, lAdd, bMd5); Cmpp3_Connect connect={0}; strcpy(connect.Source_Addr,m_szCmpp3User); //if ( atol(m_szCmpp3User)>=100000 && atol(m_szCmpp3User)<200000 ) //连接到短信易cmpp协议时,不用加密 //memcpy(connect.AuthenticatorSource,m_szCmpp3Passwd,strlen(m_szCmpp3Passwd)<16?strlen(m_szCmpp3Passwd):16); if ( m_lPort == CMPP3_EXCHANGE_PORT || m_lPort == CMPP3_EXCHANGE_PORT2 ) ; else memcpy(connect.AuthenticatorSource,bMd5,16); connect.Version = 0x30; connect.Timestamp = atol(str); connect.Timestamp = htonl(connect.Timestamp); m_bLoginCmpp3 = -1; ULONG lSeq=0; if ( !SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_CONNECT,(UCHAR*)&connect,sizeof(connect),lSeq) ) return -2; //发送数据失败 //重新连接时,需要重发短信 // memset(m_pSendList,0,sizeof(Cmpp3_Send_List)*CMPP3_SMS_MAX_LIST); /* for ( int i=0 ; i< CMPP3_SMS_MAX_LIST ;i++ ) { if ( m_pSendList[i].lSendID > 0 ) { m_pSendList[i].lReSendCount = 0; m_pSendList[i].lSendTime = 0; m_pSendList[i].lSeq = 0; } } */ return -4; //其它错误 } long CCmpp3::Back_Send() { /* //因为上层会判断超时,即使网关断线情况下仍要继续发送 if ( m_bLoginCmpp3 != 0 ) //还没登录成功,不能发短信 { return 0; } */ long lCount = 0; for (int i = 0; i < 100; i++) { Cmpp3_Send_List* pSend = 0; if (Sms_Get(pSend) && pSend) { BOOL bSend = false; if (pSend->lReSendCount > 0) //前已发送过,看是否到达重发时间 { if (::GetTickCount() - pSend->lSendTime > CMPP3_SENDSMS_TIMEOUT) bSend = true; else bSend = false; } else { bSend = true; //第一次发送 } if (bSend) { if (pSend->lReSendCount >= CMPP3_SENDSMS_RECOUNT) //发送失败 { //插入发送返回 Cmpp3_Send_Resp Resp = { 0 }; Resp.lSendID = pSend->lSendID; Resp.lReSendCount = pSend->lReSendCount; Resp.lResult = -1; //发送失败 SendResp_Add(Resp); pSend->lSendID = 0; //已删除 } else { if (m_lSendInterval > 0) //控制发送速度 { m_lSendIntervalIndex++; if (m_lSendIntervalIndex >= m_lSendIntervalCount) { Sleep_Lu(m_lSendInterval); m_lSendIntervalIndex = 0; } } m_dwEndSocketSendTime = GetTickCount(); //用于控制发送速度 //以下为群发 //sendList.AddTail(pSend); //lCount ++; //以下为单发 if (Socket_SendSms(pSend)) lCount++; } } } else { break; } } /* if ( m_bLoginCmpp3 != 0 ) //还没登录成功,不能发短信 return 0; CSendList_Cmpp3 sendList; EnterCriticalSection(&m_CriSendSms); //防止冲突 long lCount = 0; for ( int i=0 ; i< CMPP3_SMS_MAX_LIST;i++ ) { Cmpp3_Send_List * pSend = &m_pSendList[i]; if ( pSend->lSendID == 0 ) continue; BOOL bSend = false; if ( pSend->lReSendCount > 0 ) //前已发送过,看是否到达重发时间 { if ( ::GetTickCount()-pSend->lSendTime>CMPP3_SENDSMS_TIMEOUT ) bSend = true; else bSend = false; } else { bSend = true; //第一次发送 } if ( bSend ) { if ( pSend->lReSendCount >= CMPP3_SENDSMS_RECOUNT ) //发送失败 { //插入发送返回 Cmpp3_Send_Resp Resp={0}; Resp.lSendID = pSend->lSendID; Resp.lReSendCount = pSend->lReSendCount; Resp.lResult = -1; //发送失败 SendResp_Add(Resp); pSend->lSendID = 0 ; //已删除 } else { if (m_lSendInterval>0 ) //控制发送速度 { long lDelay=m_lSendInterval-(long)(GetTickCount()-m_dwEndSocketSendTime); if ( lDelay>0 && lDelaySubmit)+pSend->Submit.Msg_Length+20; //计算发送信息的总长度 #else long lDataLen = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+8; //计算发送信息的总长度 #endif Cmpp3_Head head={0}; long lAllLen; ULONG lSeq=0; head.Total_Length = sizeof(head)+lDataLen; lAllLen = head.Total_Length; head.Command_Id = CMPP3_SUBMIT; if ( m_lID >= 0xF000000 ) //重新开始序号 m_lID = 1; if ( lSeq > 0 ) head.Sequence_Id = lSeq; //直接使用相同序号的发送 else head.Sequence_Id = m_lID++; lSeq = head.Sequence_Id; //返回 head.Total_Length = htonl(head.Total_Length); head.Command_Id = htonl(head.Command_Id); head.Sequence_Id = htonl(head.Sequence_Id); m_dwEndSendTime = ::GetTickCount(); //记录最后发送时间 //BYTE * pSData = new BYTE[lAllLen]; //添加头 memcpy(pData+lSmsPickLen,&head,sizeof(head));lSmsPickLen = lSmsPickLen + sizeof(head); //submit头 memcpy(pData+lSmsPickLen,(void*)&pSend->Submit,sizeof(Cmpp3_Submit));lSmsPickLen = lSmsPickLen + sizeof(Cmpp3_Submit); //短信内容 memcpy(pData+lSmsPickLen,pSend->Msg,pSend->Submit.Msg_Length);lSmsPickLen = lSmsPickLen + pSend->Submit.Msg_Length; #ifdef CMPP3_3_0 lSmsPickLen += 20; #else lSmsPickLen += 8; #endif pSend->lReSendCount ++; pSend->lSendTime = ::GetTickCount(); pSend->lSeq = lSeq; } EnterCriticalSection(&m_CriSendFrame); //防止冲突 BOOL bOK = Send(m_hSocket,(BYTE*)pData , lSmsPickLen ); LeaveCriticalSection(&m_CriSendFrame); //防止冲突 delete pData; */ return lCount; } BOOL CCmpp3::Socket_SendSms(Cmpp3_Send_List *pSend) { #ifdef CMPP3_3_0 long lSize = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+20; //计算发送信息的总长度 #else long lSize = sizeof(pSend->Submit)+pSend->Submit.Msg_Length+8; //计算发送信息的总长度 #endif BYTE * pData = new BYTE[lSize]; memset(pData,0,lSize); Cmpp3_Submit * pSubmit = (Cmpp3_Submit*)pData; BYTE * pMsg = (BYTE*)(pData+sizeof(Cmpp3_Submit)); *pSubmit = pSend->Submit; memcpy(pMsg,pSend->Msg,pSend->Submit.Msg_Length); ULONG lSeq=0; BOOL b = SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_SUBMIT,pData,lSize,lSeq); //if ( b ) //{ pSend->lReSendCount ++; pSend->lSendTime = ::GetTickCount(); pSend->lSeq = lSeq; //} delete pData; return b; } long CCmpp3::Process_Submit(Cmpp3_Head head,BYTE *pData, long lLen) { Cmpp3_Submit_Resp * pResp = (Cmpp3_Submit_Resp *)pData; /* CString str; str.Format( "提交短信返回代码:%d" , pResp->Result ); AfxMessageBox(str); */ #ifdef CMPP3_3_0 pResp->Result = ntohl(pResp->Result); #endif //收到发送返回,在队列中查找发送信息 Cmpp3_Send_List * pSendSms = NULL; BOOL bFind = false; ULONG lSeq = head.Sequence_Id; for ( int i=0 ; i< CMPP3_SMS_MAX_LIST;i++ ) { pSendSms = &m_pSendList[i]; if ( pSendSms->lSendID!=0 && pSendSms->lSeq == lSeq ) { bFind = true; break; } } if ( bFind ) { if ( pSendSms->lSendID <= MAX_CMPP3EXCHANGE+10 ) //小于-100表示cmpp转接所发 { Cmpp3ExchangeResp resp={0}; resp.lType = 0; resp.lSendID = pSendSms->lSendID; resp.lLen = lLen; resp.lCmd = head.Command_Id; resp.lSeq = pSendSms->lCmpp3Seq; memcpy(resp.Data , pData , lLen ); Cmpp3ExchangeResp_Add(resp); pSendSms->lSendID = 0; //删除此记录 } else { Cmpp3_Send_Resp Resp={0}; Resp.lSendID = pSendSms->lSendID; Resp.lReSendCount = pSendSms->lReSendCount; ULONG * lMsgID1 = (ULONG*)&pResp->Msg_ID; ULONG * lMsgID2 = (ULONG*)((char*)&pResp->Msg_ID+sizeof(long)); ULONG * lMsgID21= (ULONG*)&Resp.lMsgID; ULONG * lMsgID22= (ULONG*)((char*)&Resp.lMsgID+sizeof(long)); //取ID *lMsgID21 = ntohl(*lMsgID2); *lMsgID22 = ntohl(*lMsgID1); //pSend->lMsgID = pResp->Msg_ID; Resp.lResult = pResp->Result; SendResp_Add(Resp); pSendSms->lSendID = 0; //删除此记录 } } return 1; } BOOL CCmpp3::GetSendResp(Cmpp3_Send_Resp &resp) { EnterCriticalSection(&m_CriRespList); //防止冲突 //从当前点到结尾 int i=0; for ( i=m_lRespList ; i< CMPP3_SMS_MAX_RESP; i++ ) { if ( m_pRespList[i].lSendID != 0 ) //其等于0时,认为此位置为空 { m_lRespList = i+1; resp = m_pRespList[i]; m_pRespList[i].lSendID = 0; LeaveCriticalSection(&m_CriRespList); //防止冲突 return true; } } //从开头到当前点 for ( i=0 ; iRegistered_Delivery*/ ) //只转发状态报告,上行短信不转发 { char szTemp[32]={0}; strcpy( szTemp , (char*)pDeliver->Dest_Id+10 ); szTemp[4]=0; lExNum = atol(szTemp); if ( lExNum>=3800 && lExNum<4499 && lExNum!=4474 ) { strcpy(szTemp , (char*)pDeliver->Dest_Id+14 ); szTemp[6]=0; sprintf((char*)pDeliver->Dest_Id , "1065710055%s",szTemp ); //这类特殊的转换直接使用总端口 } } for ( int i=0 ; iDest_Id,m_pCmppExchange[i].szNum,strlen(m_pCmppExchange[i].szNum) ) ) { Cmpp3ExchangeResp resp={0}; resp.lType = 1; strcpy(resp.szNum , m_pCmppExchange[i].szNum ); resp.lExNum = lExNum; //adc特殊转发时用到 resp.lLen = lLen; resp.lCmd = head.Command_Id; resp.lSeq = head.Sequence_Id; memcpy(resp.Data , pData , lLen ); Cmpp3ExchangeResp_Add(resp); bExchange = true; break; } } } if ( !bExchange) { Cmpp3_Deliver_List Deliver={0}; Deliver.lSendID = 1; //取ID ULONG * lMsgID1 = (ULONG*)&pDeliver->Msg_ID; ULONG * lMsgID2 = (ULONG*)((char*)&pDeliver->Msg_ID+sizeof(long)); ULONG * lMsgID21= (ULONG*)&Deliver.deliver.Msg_ID; ULONG * lMsgID22= (ULONG*)((char*)&Deliver.deliver.Msg_ID+sizeof(long)); *lMsgID21 = ntohl(*lMsgID2); *lMsgID22 = ntohl(*lMsgID1); strcpy((char*)Deliver.deliver.Dest_Id , (char*)pDeliver->Dest_Id); strcpy((char*)Deliver.deliver.Service_Id , (char*)pDeliver->Service_Id); Deliver.deliver.TP_pid = pDeliver->TP_pid; Deliver.deliver.TP_udhi = pDeliver->TP_udhi; Deliver.deliver.Msg_Fmt = pDeliver->Msg_Fmt; strcpy((char*)Deliver.deliver.Src_terminal_Id,(char*)pDeliver->Src_terminal_Id); Deliver.deliver.Registered_Delivery = pDeliver->Registered_Delivery; Deliver.deliver.Msg_Length = pDeliver->Msg_Length; memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); //取信息内容 /* if ( pMsgData[0] == 0x59 && pMsgData[1] == 0x4E && (pMsgData[2] >= 0x01 && pMsgData[2] <= 0x04) && (pMsgData[3] >= 0x01 && pMsgData[3] <= 0x31) ) { if ( Deliver.deliver.Msg_Length > 70 ) Deliver.deliver.Msg_Length = 70; AsciiToHex((char*)pMsgData,(TCHAR*)Deliver.szMsg,Deliver.deliver.Msg_Length); //转换成hex码 Deliver.deliver.Msg_Length= Deliver.deliver.Msg_Length*2; Deliver.deliver.Msg_Fmt = 0; //改变编码 //memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); } else { memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); //取信息内容 } */ memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.Msg_Length ); //取信息内容 if ( Deliver.deliver.Registered_Delivery ) //是状态报告 { memcpy(&Deliver.status,pMsgData,sizeof(Deliver.status)); /* CString str; str.Format( "状态报告返回代码:%s" , Deliver.status.Stat ); AfxMessageBox(str); */ //取ID LONGLONG lTemp; ULONG * lMsgID1 = (ULONG*)&Deliver.status.Msg_ID; ULONG * lMsgID2 = (ULONG*)((char*)&Deliver.status.Msg_ID+sizeof(long)); ULONG * lMsgID21= (ULONG*)&lTemp; ULONG * lMsgID22= (ULONG*)((char*)&lTemp+sizeof(long)); *lMsgID21 = ntohl(*lMsgID2); *lMsgID22 = ntohl(*lMsgID1); Deliver.status.Msg_ID = lTemp; Status_Add(Deliver); //添加到列表 } else { /* if (Deliver.deliver.Msg_Fmt == 8 ) //ucs2,要编码 { memset(Deliver.szMsg,0,sizeof(Deliver.szMsg)); UCS2ToAscii2((char*)pMsgData,(char*)Deliver.szMsg,Deliver.deliver.Msg_Length); } */ Deliver_Add(Deliver); //添加到列表 } } //发送返回 Cmpp3_Deliver_Resp resp={0}; resp.Msg_ID = pDeliver->Msg_ID; resp.Result = 0; ULONG lReq=head.Sequence_Id; SendFrame(m_hSocket,m_lID,m_dwEndSendTime,CMPP3_DELIVER_RESP,(BYTE*)&resp,sizeof(resp),lReq); return true; } BOOL CCmpp3::GetDeliver(Cmpp3_Deliver_List &deliver) { EnterCriticalSection(&m_CriDeliverList); //防止冲突 //从当前点到结尾 int i=0; for ( i=m_lDeliverList ; i< CMPP3_SMS_MAX_DELIVER; i++ ) { if ( m_pDeliverList[i].lSendID != 0 ) //其等于0时,认为此位置为空 { m_lDeliverList = i+1; deliver = m_pDeliverList[i]; m_pDeliverList[i].lSendID = 0; LeaveCriticalSection(&m_CriDeliverList); //防止冲突 return true; } } //从开头到当前点 for ( i=0 ; i(70-ludhiLen/2) ) lSrcLen=(70-ludhiLen/2); for ( int i=0 ; i(70-ludhiLen/2) ) lSrcLen=(70-ludhiLen/2); for ( int i=0 ; i128 ) { return true; } } return false; #else char szBuf[4096]; long l = MultiByteToWideChar( CP_ACP,NULL,pSrc,lLen, (LPWSTR)szBuf , sizeof(szBuf) ); if ( l == lLen ) return false; else return true; #endif } long CCmpp3::AsciiToUCS2(const char *pAscii, WCHAR *pUCS2) { long lLen = (long)strlen( pAscii ); long l = MultiByteToWideChar( CP_ACP,NULL,pAscii,lLen, pUCS2 , 4096 ); pUCS2[l]=0; return l; } void CCmpp3::HexToAscii(const char *pszOrgRandom, char *pszDesRandom) { char Buf[4]; char *pDes = (char *)pszDesRandom; char *pOrg = (char *)pszOrgRandom; long lLen = (long)strlen( pOrg); long lTemp; int i=0; for( i = 0; i < lLen/2; ++i ) { memcpy( Buf , pOrg+i*2 , 2 ); Buf[2] = 0; lTemp = CharHex(Buf[0])*16 + CharHex(Buf[1]); pDes[i] = (char)lTemp; } pDes[i] = 0; } void CCmpp3::ExchangeUniCode(char *pData) { char pEx[4]; long lLen = (long)strlen( pData ); for ( int i = 0 ; i< lLen/4 ; i++ ) { memcpy( pEx , pData+i*4 , 2 ); memcpy( pData+i*4 , pData+i*4+2 , 2 ); memcpy( pData+i*4+2 , pEx , 2 ); } } void CCmpp3::AsciiToHex(const char *pszOrgRandom, TCHAR *pszDesRandom, long lLen) { #ifdef _UNICODE TCHAR *p = (TCHAR *)pszDesRandom; //long lLen = lstrlen( (char*)pszOrgRandom); for( long i = 0; i < lLen; ++i ) { _stprintf(p, _T("%02X"), (BYTE)pszOrgRandom[i] ); p += 2; } *p=0; #else char *p = (char *)pszDesRandom; //long lLen = lstrlen( (char*)pszOrgRandom); for( long i = 0; i < lLen; ++i ) { sprintf(p, "%02X", (BYTE)pszOrgRandom[i] ); p += 2; } *p=0; #endif } int CCmpp3::CharHex(char ch) { //if( isdigit( ch ) ) return( atoi( &ch) ); if( ch >='0' && ch <= '9' ) return( atoi( &ch) ); else { if( ch == 'a' || ch == 'A' ) return( 10 ); if( ch == 'b' || ch == 'B' ) return( 11 ); if( ch == 'c' || ch == 'C' ) return( 12 ); if( ch == 'd' || ch == 'D' ) return( 13 ); if( ch == 'e' || ch == 'E' ) return( 14 ); if( ch == 'f' || ch == 'F' ) return( 15 ); } return( 0 ); } BOOL CCmpp3::GetStatus(Cmpp3_Deliver_List &deliver) { EnterCriticalSection(&m_CriStatusList); //防止冲突 //从当前点到结尾 int i=0; for ( i=m_lStatusList ; i< CMPP3_SMS_MAX_STATUS; i++ ) { if ( m_pStatusList[i].lSendID != 0 ) //其等于0时,认为此位置为空 { m_lStatusList = i+1; deliver = m_pStatusList[i]; m_pStatusList[i].lSendID = 0; LeaveCriticalSection(&m_CriStatusList); //防止冲突 return true; } } //从开头到当前点 for ( i=0 ; i70 ) deliver.deliver.Msg_Length=70; AsciiToHex((const char*)pMsg,((TCHAR*)Msg)+6,lMsgLen); //AsciiToHex((const char*)pMsg,(char*)Msg+6,lMsgLen); } else { _tcscpy((WCHAR*)Msg,CA2W((char*)pMsg)); //AsciiToUCS2((const char*)pMsg , (TCHAR*)Msg); //memcpy(Msg,pMsg,lMsgLen); } } } return 0; } else { AsciiToHex((const char*)deliver.szMsg,(TCHAR*)Msg,deliver.deliver.Msg_Length); //转换成Hex编码 //memcpy(Msg,deliver.szMsg,deliver.deliver.Msg_Length); if ( Msg_Fmt ) _stprintf( Msg_Fmt , _T("%d") , deliver.deliver.Msg_Fmt ); if ( Msg_Length ) _stprintf( Msg_Length , _T("%d") , deliver.deliver.Msg_Length*2 ); return 0; } } return -1; //没有信息 } long CCmpp3::Cmpp3_GetReport(TCHAR *No, TCHAR *Stat, TCHAR *Done_time, TCHAR *MsgID) { Cmpp3_Deliver_List deliver={0}; if ( GetStatus(deliver) ) { _tcscpy( No , CA2W((char*)deliver.status.Dest_terminal_Id) ); //strcpy( Stat , (char*)deliver.status.Stat ); _tcsncpy( Stat , CA2W((char*)deliver.status.Stat) , 7 ); //strcpy( Done_time , (char*)deliver.status.Done_time ); _tcsncpy( Done_time , CA2W((char*)deliver.status.Done_time) , 10 ); _stprintf( MsgID , _T("%I64u") , deliver.status.Msg_ID ); return 0; } return -1; //没有信息 } BOOL CCmpp3::GetCmpp3ExchangeResp(Cmpp3ExchangeResp &resp) { EnterCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突 //从当前点到结尾 int i=0; for ( i=m_lCmpp3ExchangeRespList ; i< CMPP3_SMS_MAX_CMPP3EXCHANGERESP; i++ ) { if ( m_pCmpp3ExchangeResp[i].lLen != 0 ) //其等于0时,认为此位置为空 { m_lCmpp3ExchangeRespList = i+1; resp = m_pCmpp3ExchangeResp[i]; m_pCmpp3ExchangeResp[i].lLen = 0; LeaveCriticalSection(&m_CriCmpp3ExchangeResp); //防止冲突 return true; } } //从开头到当前点 for ( i=0 ; i= 15) { m_lSendIntervalCount = 1; m_lSendIntervalIndex = 0; } else { m_lSendInterval = 15; m_lSendIntervalCount = (int)((double)m_lSendInterval / dwInterval + 0.5f); if (m_lSendIntervalCount * dwInterval > m_lSendInterval) m_lSendInterval = (int)(m_lSendIntervalCount * dwInterval + 0.5f); } } } long CCmpp3::GetWFSms() { long lWF=0; //从当前点到结尾 for ( int i=0 ; i< CMPP3_SMS_MAX_LIST; i++ ) { if ( m_pSendList[i].lSendID != 0 ) //其等于0时,认为此位置为空 { lWF++; } } return lWF; } long CCmpp3::GetReportSms() { long lReport=0; //从当前点到结尾 for ( int i=0 ; i< CMPP3_SMS_MAX_STATUS; i++ ) { if ( m_pStatusList[i].lSendID != 0 ) //其等于0时,认为此位置为空 { lReport++; } } return lReport; } CString CCmpp3::GetErrMsg() { EnterCriticalSection(&m_CriErrMsg); //防止冲突 CString strRet; if ( m_strErrMsg.GetLength()>0 ) { strRet = m_strErrMsg; m_strErrMsg = CString(_T("")); } LeaveCriticalSection(&m_CriErrMsg); //防止冲突 return strRet; } void CCmpp3::SetErrMsg(CString str) { EnterCriticalSection(&m_CriErrMsg); //防止冲突 m_strErrMsg = str; LeaveCriticalSection(&m_CriErrMsg); //防止冲突 } BOOL CCmpp3::isConnectGateWay() { if ( m_bLoginCmpp3 == 0 ) { return true; } return false; } long CCmpp3::UCS2ToAscii( const WCHAR * pUCS2 , char * pAscii) { long lLen = (long)wcslen( pUCS2 ); long l = WideCharToMultiByte(CP_ACP,NULL,pUCS2,lLen, pAscii , 4096 ,NULL,NULL); pAscii[l]=0; return l; } BOOL CCmpp3::Sms_Get(Cmpp3_Send_List*& pSms) { EnterCriticalSection(&m_CriSendSms); //防止冲突 //从当前点到结尾 int i = 0; for (i = m_lSendList; i < CMPP3_SMS_MAX_LIST; i++) { if (m_pSendList[i].lSendID != 0) //其等于0时,认为此位置为空 { m_lSendList = i + 1; pSms = &m_pSendList[i]; //m_pSendList[i].lSendID = 0; LeaveCriticalSection(&m_CriSendSms); //防止冲突 return true; } } //从开头到当前点 for (i = 0; i < m_lSendList; i++) { if (m_pSendList[i].lSendID != 0) //其等于0时,认为此位置为空 { m_lSendList = i + 1; pSms = &m_pSendList[i]; //m_pSendList[i].lSendID = 0; LeaveCriticalSection(&m_CriSendSms); //防止冲突 return true; } } m_lSendList = 0; LeaveCriticalSection(&m_CriSendSms); //防止冲突 return false; } BOOL CCmpp3::Sms_Add(Cmpp3_Send_List sms) { EnterCriticalSection(&m_CriSendSms); //防止冲突 //从当前点到结尾 int i = 0; for (i = m_lSendList; i < CMPP3_SMS_MAX_LIST; i++) { if (m_pSendList[i].lSendID == 0) //其等于0时,认为此位置为空 { m_pSendList[i] = sms; LeaveCriticalSection(&m_CriSendSms); //防止冲突 return true; } } //从开头到当前点 for (i = 0; i < m_lSendList; i++) { if (m_pSendList[i].lSendID == 0) //其等于0时,认为此位置为空 { m_pSendList[i] = sms; LeaveCriticalSection(&m_CriSendSms); //防止冲突 return true; } } LeaveCriticalSection(&m_CriSendSms); //防止冲突 return false; }