FXSend/Sgip/Sgip.cpp
lujiang 53133d3841 1、增加签名校验功能,在TD2Signature表中有的记录才允许发送。
2、CSgip,修改了发送规则,断连时等到连接恢复后再发送短信
2025-03-19 16:47:14 +08:00

2146 lines
51 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Sgip.cpp: implementation of the CSgip class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Sgip.h"
//#include "MSgip.h"
/*
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
CSgip::CSgip()
{
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_pRecvProc = NULL;
m_bConnect = false;
m_bLoginSgip= -1;
m_bInitSgip = false;
memset(m_szSgipIP ,0,sizeof(m_szSgipIP));
memset(m_szSgipUser ,0,sizeof(m_szSgipUser));
memset(m_szSgipPasswd,0,sizeof(m_szSgipPasswd));
memset(m_szSgipCorpID,0,sizeof(m_szSgipCorpID));
WSADATA wsaData; //用于初始化socket的结构
//以下为初始化SOCKET环境
int iTemp=WSAStartup(0x0101,&wsaData); //初始化socket环境
InitializeCriticalSection(&m_CriSendSms);
InitializeCriticalSection(&m_CriRespList);
InitializeCriticalSection(&m_CriDeliverList);
InitializeCriticalSection(&m_CriStatusList);
InitializeCriticalSection(&m_CriSgipExchangeResp);
InitializeCriticalSection(&m_CriErrMsg);
//定义队列
m_lSendID = 1;
m_pSendList = new Sgip_Send_List[SGIP_SMS_MAX_LIST];
m_pRespList = new Sgip_Send_Resp[SGIP_SMS_MAX_RESP];
m_pDeliverList = new Sgip_Deliver_List[SGIP_SMS_MAX_DELIVER];
m_pStatusList = new Sgip_Deliver_List[SGIP_SMS_MAX_STATUS];
m_pSgipExchangeResp = new SgipExchangeResp[SGIP_SMS_MAX_SGIPEXCHANGERESP];
memset(m_pSendList,0,sizeof(Sgip_Send_List)*SGIP_SMS_MAX_LIST);
memset(m_pRespList,0,sizeof(Sgip_Send_Resp)*SGIP_SMS_MAX_RESP);
memset(m_pDeliverList,0,sizeof(Sgip_Deliver_List)*SGIP_SMS_MAX_DELIVER);
memset(m_pStatusList,0,sizeof(Sgip_Deliver_List)*SGIP_SMS_MAX_STATUS);
memset(m_pSgipExchangeResp,0,sizeof(SgipExchangeResp)*SGIP_SMS_MAX_SGIPEXCHANGERESP);
m_lSendList = 0;
m_lRespList = 0;
m_lDeliverList=0;
m_lStatusList=0;
m_lSgipExchangeRespList=0;
m_pSgipExchange = NULL;
m_lSgipExchange = 0;
m_bAdc = false;
//用于接收信息
m_hRecv_Socket = INVALID_SOCKET;
memset(&m_szRecvIP,0,sizeof(m_szRecvIP));
m_lRecvPort=8802;
m_bRecvInit=false;
m_bQuitThread_Recv=false;
m_hThread = INVALID_HANDLE_VALUE;
m_hThread_Recv = INVALID_HANDLE_VALUE;
m_hThread_Send = INVALID_HANDLE_VALUE;
//用于控制发送速度
m_dwEndSocketSendTime = 0;
m_lSendInterval = 0;
m_lSendIntervalCount = 1;
m_lSendIntervalIndex = 0;
}
CSgip::~CSgip()
{
Stop();
if ( m_hSocket != INVALID_SOCKET )
closesocket(m_hSocket);
Sgip_Recv_Exit();
//删除数据
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_pSgipExchangeResp )
{delete m_pSgipExchangeResp;m_pSgipExchangeResp=NULL;}
DeleteCriticalSection(&m_CriSendSms);
DeleteCriticalSection(&m_CriRespList);
DeleteCriticalSection(&m_CriDeliverList);
DeleteCriticalSection(&m_CriStatusList);
DeleteCriticalSection(&m_CriSgipExchangeResp);
DeleteCriticalSection(&m_CriErrMsg);
//退出Socket
WSACleanup();
}
BOOL CSgip::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 )
{
Close();
return false;
}
SetThreadPriority(m_hThread,THREAD_PRIORITY_LOWEST); //设置优先级
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_Send, THREAD_PRIORITY_LOWEST); //设置优先级
m_bConnect = true;
return true;
}
BOOL CSgip::Connect2()
{
m_bConnect = false;
if ( m_hSocket != INVALID_SOCKET )
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
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)); //设绶冲
m_bConnect = true;
return true;
}
BOOL CSgip::isConnect()
{
return m_bConnect;
}
void CSgip::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;
Sgip_Recv_Exit(); //退出接收
if (m_hThread_Recv != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread_Recv,2000) == WAIT_TIMEOUT ) //等待5秒让线程退出
{
TerminateThread(m_hThread_Recv,0); //如果退出超时,强制结束线程
}
m_hThread_Recv = 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 CSgip::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 CSgip::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 CSgip::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 CSgip::SocketRecv(LPVOID lParam)
{
CSgip * pNet = (CSgip *)lParam;
Sgip_Data_Recv Drecv={0};
pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间
DWORD dwEndSendBindFrame=0;
while ( !pNet->m_bQuitThread )
{
if ( pNet->m_bConnect && isSocketClose(pNet->m_hSocket) )
{
pNet->Close();
//重新接收数据
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
memset(&Drecv,0,sizeof(Drecv));
//pNet->InitSgip2(); //重新连接到服务器
}
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 >SGIP_ACTIVE_TIMEOUT*2 ) //接收超时
if ( pNet->m_dwEndSendTime>0 && (pNet->m_dwEndSendTime>pNet->m_dwEndRecvTime)&& (::GetTickCount() - pNet->m_dwEndSendTime >SGIP_ACTIVE_TIMEOUT*2) ) //接收超时
{
pNet->m_dwEndRecvTime = ::GetTickCount()-SGIP_ACTIVE_TIMEOUT; //如果接收超时,重新计数
pNet->Close();
//重新接收数据
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
memset(&Drecv,0,sizeof(Drecv));
//pNet->InitSgip2(); //重新连接到服务器
}
//判断是否应该发送Active_Test指令
if ( strlen(pNet->m_szSgipUser)<=2 && pNet->m_dwEndSendTime > 0 )
{
if ( ::GetTickCount() - pNet->m_dwEndSendTime > SGIP_ACTIVE_TESTTIME ) //重新连接
{
Sgip_SeqID lSeq = { 0 };
pNet->SendFrame(pNet->m_hSocket,pNet->m_lNodeID,pNet->m_lID,pNet->m_dwEndSendTime, SGIP_ACTIVE_TEST , NULL , 0 ,lSeq );
}
}
//发送短信
if ( pNet->m_bConnect && pNet->m_bLoginSgip==0 )
{
//dwEndSendBindFrame = 0;
//long lCount2 = pNet->Back_Send();
//if ( lCount2>0 )
// Sleep_Lu(2);
//else
// Sleep_Lu(20);
}
else
{
if ( pNet->m_bInitSgip && (dwEndSendBindFrame==0 || (dwEndSendBindFrame>0 && GetTickCount()-dwEndSendBindFrame>10000)) ) //如果已初始化的,则按需看是否重新连接,如果上次连接还没超时则不重发。
{
BOOL bReConnect=false;
for ( int i=0 ; i<SGIP_SMS_MAX_LIST;i++ )
{
Sgip_Send_List * pSend = &pNet->m_pSendList[i];
if ( pSend->lSendID != 0 )
{
bReConnect = true;
break;
}
}
if ( bReConnect )
{
pNet->m_bLoginSgip = -1;
pNet->SetErrMsg("Sgip消息:正在重连网关...");
pNet->InitSgip2(); //重新连接到服务器
dwEndSendBindFrame = GetTickCount();
}
}
}
//Sleep_Lu(2);
}
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
pNet->Close();
return 1;
}
DWORD WINAPI CSgip::SocketSend(LPVOID lParam)
{
CSgip* pNet = (CSgip*)lParam;
while (!pNet->m_bQuitThread)
{
long lCount = 0;
if (pNet->m_bConnect && pNet->m_bLoginSgip == 0)
{
//发送短信
long lCount = pNet->Back_Send();
}
if (lCount > 0)
Sleep_Lu(1);
else
Sleep_Lu(5);
}
return 1;
}
void CSgip::SetRecvProc(RECVPROC proc)
{
m_pRecvProc = proc;
}
BOOL CSgip::ReadFrame(SOCKET s, Sgip_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 = 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 CSgip::RecvFrame(Sgip_Data_Recv &Drecv)
{
Sgip_Head * pHead=(Sgip_Head *)Drecv.pRecvFrame;
if ( pHead->Total_Length != Drecv.lRecvLen )
return false;
pHead->Command_Id = ntohl(pHead->Command_Id);
pHead->SeqID.Node_Id= ntohl(pHead->SeqID.Node_Id);
pHead->SeqID.Time= ntohl(pHead->SeqID.Time);
pHead->SeqID.Sequence_Id= ntohl(pHead->SeqID.Sequence_Id);
BYTE * pData = (BYTE*)(Drecv.pRecvFrame+sizeof(Sgip_Head));
long lLen = pHead->Total_Length-sizeof(Sgip_Head);
long lRet = 0;
switch( pHead->Command_Id )
{
case SGIP_BIND_RESP:
lRet = Process_Bind(*pHead,pData,lLen);
break;
case SGIP_SUBMIT_RESP:
lRet = Process_Submit(*pHead,pData,lLen);
break;
case SGIP_ACTIVE_TEST:
lRet = Process_Active(*pHead,pData,lLen);
break;
case SGIP_DELIVER:
lRet = Process_Deliver(m_hSocket,*pHead,pData,lLen);
break;
case SGIP_REPORT:
lRet = Process_Report(m_hSocket,*pHead,pData,lLen);
break;
case SGIP_ACTIVE_TEST_RESP:
break;
default:
break;
}
return lRet;
}
long CSgip::Sgip_Init(const char *pIP,long lPort,long lLocalPort, const char *pUser, const char *pPasswd,const char * pCorpID,const char * pNodeID)
{
if ( !Connect(pIP,lPort) )
{
return -1; //连接服务器失败
}
//记录信息
strcpy(m_szSgipIP,pIP);
strcpy(m_szSgipUser,pUser);
strcpy(m_szSgipPasswd,pPasswd);
strcpy(m_szSgipCorpID,pCorpID);
m_lPort = lPort;
m_lLocalPort = lLocalPort;
m_lNodeID=atol(pNodeID)*100000+atol(pCorpID); //生成节点编号
Sgip_Bind bind={0};
bind.LoginType = 1;
strcpy(bind.LoginName,pUser);
strcpy(bind.LoginPasswd,pPasswd);
char szAddNum[32]={0};
long lLen = strlen(pUser);
if ( lLen>2 )
{
m_lID=atol(pUser+(lLen-2))*0x1000000;
}
else
{
m_lID=1;
}
m_bLoginSgip = -1;
Sgip_SeqID lSeq={0};
if ( !SendFrame(m_hSocket,m_lNodeID,m_lID,m_dwEndSendTime,SGIP_BIND,(UCHAR*)&bind,sizeof(bind),lSeq) )
return -2; //发送数据失败
long lTime = ::GetTickCount();
while ( m_bLoginSgip == -1 )
{
if ( ::GetTickCount()-lTime > 30000 ) //超时了
break;
Sleep_Lu(20);
}
if ( m_bLoginSgip==0 )
m_bInitSgip = true; //已初始化
if ( m_bLoginSgip == -1 )
return -3; //登录超时
else
return m_bLoginSgip; //登录返回成功,具体请看错误码
return -4; //其它错误
}
long CSgip::SendFrame(SOCKET sock,ULONG lNodeID , ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,UCHAR *pData, long lDataLen,Sgip_SeqID & lSeq )
{
Sgip_Head head={0};
long lAllLen;
head.Total_Length = sizeof(head)+lDataLen;
lAllLen = head.Total_Length;
head.Command_Id = lCommandID;
//if ( lID >= 0xF000000 ) //重新开始序号
// lID = 1;
if ( lSeq.Sequence_Id > 0 )
head.SeqID = lSeq; //直接使用相同序号的发送
else
{
//生成顺序号
head.SeqID.Node_Id = lNodeID;
SYSTEMTIME t;::GetLocalTime(&t);
head.SeqID.Time=t.wMonth*100000000+t.wDay*1000000+t.wHour*10000+t.wMinute*100+t.wSecond;
head.SeqID.Sequence_Id = lID++;
}
lSeq = head.SeqID; //返回
head.Total_Length = htonl(head.Total_Length);
head.Command_Id = htonl(head.Command_Id);
head.SeqID.Node_Id=htonl(head.SeqID.Node_Id);
head.SeqID.Time =htonl(head.SeqID.Time);
head.SeqID.Sequence_Id=htonl(head.SeqID.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;
if ( bOK )
return true;
else
return false;
return false;
}
long CSgip::Process_Bind(Sgip_Head head,BYTE *pData, long lLen)
{
Sgip_Bind_Resp * pResp = (Sgip_Bind_Resp *)pData;
if ( m_bInitSgip && pResp->Result != 0 ) //需要重新登录
{
//InitCmpp2();
//登录不成功,关闭连接
this->Close();
}
CString str;
str.Format(_T("Sgip消息:连接网关返回代码:%d") , pResp->Result );
SetErrMsg(str);
m_bLoginSgip = pResp->Result;
return 1;
}
BOOL CSgip::SendSms(Sgip_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;
/*
for ( int j=0 ; j< 200 ; j++ )
{
//从当前点到结尾
EnterCriticalSection(&m_CriSendSms); //防止冲突
for ( int i=0 ; i< SGIP_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(50); //延时10秒
}
return false;
*/
}
BOOL CSgip::InitSgip2()
{
if ( !Connect2() )
{
return false; //连接服务器失败
}
Sgip_Bind bind={0};
bind.LoginType = 1;
strcpy(bind.LoginName,m_szSgipUser);
strcpy(bind.LoginPasswd,m_szSgipPasswd);
m_bLoginSgip = -1;
Sgip_SeqID lSeq={0};
if ( !SendFrame(m_hSocket,m_lNodeID,m_lID,m_dwEndSendTime,SGIP_BIND,(UCHAR*)&bind,sizeof(bind),lSeq) )
return -2; //发送数据失败
//重新连接时,需要重发短信
// memset(m_pSendList,0,sizeof(Sgip_Send_List)*SGIP_SMS_MAX_LIST);
/*
for ( int i=0 ; i< SGIP_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 CSgip::Back_Send()
{
long lCount = 0;
for (int i = 0; i < 100; i++)
{
Sgip_Send_List* pSend = 0;
if (Sms_Get(pSend) && pSend)
{
BOOL bSend = false;
if (pSend->lReSendCount > 0) //前已发送过,看是否到达重发时间
{
if (::GetTickCount() - pSend->lSendTime > SGIP_SENDSMS_TIMEOUT)
bSend = true;
else
bSend = false;
}
else
{
bSend = true; //第一次发送
}
if (bSend)
{
if (pSend->lReSendCount >= SGIP_SENDSMS_RECOUNT) //发送失败
{
//插入发送返回
Sgip_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_bLoginSgip != 0 ) //还没登录成功,不能发短信
return 0;
EnterCriticalSection(&m_CriSendSms); //防止冲突
long lCount = 0;
for ( int i=0 ; i<SGIP_SMS_MAX_LIST;i++ )
{
Sgip_Send_List * pSend = &m_pSendList[i];
if ( pSend->lSendID == 0 )
continue;
BOOL bSend = false;
if ( pSend->lReSendCount > 0 ) //前已发送过,看是否到达重发时间
{
if ( ::GetTickCount()-pSend->lSendTime>SGIP_SENDSMS_TIMEOUT )
bSend = true;
else
bSend = false;
}
else
{
bSend = true; //第一次发送
}
if ( bSend )
{
if ( pSend->lReSendCount >= SGIP_SENDSMS_RECOUNT ) //发送失败
{
//插入发送返回
Sgip_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 && lDelay<m_lSendInterval+5 )
//Sleep_Lu(lDelay-lDelay/15);
Sleep_Lu(lDelay);
}
m_dwEndSocketSendTime = GetTickCount(); //用于控制发送速度
if ( Socket_SendSms(pSend) )
lCount ++;
}
}
}
LeaveCriticalSection(&m_CriSendSms); //防止冲突
*/
return lCount;
}
BOOL CSgip::Socket_SendSms(Sgip_Send_List *pSend)
{
long lSize = sizeof(pSend->Submit)+pSend->Submit.MessageLength+8; //计算发送信息的总长度
BYTE * pData = new BYTE[lSize];
memset(pData,0,lSize);
Sgip_Submit * pSubmit = (Sgip_Submit*)pData;
BYTE * pMsg = (BYTE*)(pData+sizeof(Sgip_Submit));
*pSubmit = pSend->Submit;
memcpy(pMsg,pSend->Msg,pSend->Submit.MessageLength);
pSubmit->MessageLength = htonl(pSend->Submit.MessageLength); //字节转换
Sgip_SeqID lSeq={0};
if ( pSend->lSgipSeq.Sequence_Id>0 )
lSeq = pSend->lSgipSeq;
BOOL b = SendFrame(m_hSocket,m_lNodeID,m_lID,m_dwEndSendTime,SGIP_SUBMIT,pData,lSize,lSeq);
//if ( b )
//{
pSend->lReSendCount ++;
pSend->lSendTime = ::GetTickCount();
pSend->lSeq = lSeq;
//}
delete pData;
return b;
}
long CSgip::Process_Submit(Sgip_Head head,BYTE *pData, long lLen)
{
Sgip_Submit_Resp * pResp = (Sgip_Submit_Resp *)pData;
//收到发送返回,在队列中查找发送信息
Sgip_Send_List * pSendSms = NULL;
BOOL bFind = false;
Sgip_SeqID lSeq = head.SeqID;
for ( int i=0 ; i<SGIP_SMS_MAX_LIST;i++ )
{
pSendSms = &m_pSendList[i];
if ( pSendSms->lSendID!=0 && pSendSms->lSeq.Sequence_Id == lSeq.Sequence_Id )
{
bFind = true;
break;
}
}
if ( bFind )
{
if ( pSendSms->lSendID <= MAX_SGIPEXCHANGE+10 ) //小于-100表示cmpp转接所发
{
SgipExchangeResp resp={0};
resp.lType = 0;
resp.lSendID = pSendSms->lSendID;
resp.lLen = lLen;
resp.lCmd = head.Command_Id;
//resp.lSeq = pSendSms->lSgipSeq;
resp.lSeq = head.SeqID;
memcpy(resp.Data , pData , lLen );
SgipExchangeResp_Add(resp);
pSendSms->lSendID = 0; //删除此记录
}
else
{
Sgip_Send_Resp Resp={0};
Resp.lSendID = pSendSms->lSendID;
Resp.lReSendCount = pSendSms->lReSendCount;
Resp.lMsgID = lSeq;
//转换网络字节id
//Resp.lMsgID.Node_Id=ntohl(Resp.lMsgID.Node_Id);
//Resp.lMsgID.Time =ntohl(Resp.lMsgID.Time);
//Resp.lMsgID.Sequence_Id=ntohl(Resp.lMsgID.Sequence_Id);
Resp.lResult = pResp->Result;
SendResp_Add(Resp);
pSendSms->lSendID = 0; //删除此记录
}
}
return 1;
}
BOOL CSgip::GetSendResp(Sgip_Send_Resp &resp)
{
EnterCriticalSection(&m_CriRespList); //防止冲突
//从当前点到结尾
for ( int i=m_lRespList ; i< SGIP_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 ; i<m_lRespList; 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;
}
}
m_lRespList = 0;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return false;
}
long CSgip::Process_Active(Sgip_Head head, BYTE *pData, long lLen)
{
m_dwTestCount = 0; //收到active指令检测次数为0
//发送返回
Sgip_SeqID lReq = head.SeqID;
SendFrame(m_hSocket, m_lNodeID, m_lID, m_dwEndSendTime, SGIP_DELIVER_RESP, NULL, 0, lReq);
return 1;
}
long CSgip::Process_Deliver(SOCKET sock,Sgip_Head head, BYTE *pData, long lLen)
{
Sgip_Deliver * pDeliver = (Sgip_Deliver *)pData;
BYTE * pMsgData = pData+sizeof(Sgip_Deliver);
//判断是否cmpp转接的短信内容
BOOL bExchange=false;
if ( m_pSgipExchange )
{
long lExNum=0;
for ( int i=0 ; i<m_lSgipExchange;i++ )
{
if (m_pSgipExchange[i].sock != 0 && m_pSgipExchange[i].sock != INVALID_SOCKET &&
strlen(m_pSgipExchange[i].szNum)>0 &&
!strncmp((char*)pDeliver->SPNumber,m_pSgipExchange[i].szNum,strlen(m_pSgipExchange[i].szNum) ) )
{
SgipExchangeResp resp={0};
resp.lType = 1;
strcpy(resp.szNum , m_pSgipExchange[i].szNum );
resp.lExNum = lExNum; //adc特殊转发时用到
resp.lLen = lLen;
resp.lCmd = head.Command_Id;
resp.lSeq = head.SeqID;
memcpy(resp.Data , pData , lLen );
SgipExchangeResp_Add(resp);
bExchange = true;
break;
}
}
}
if ( !bExchange)
{
Sgip_Deliver_List Deliver={0};
Deliver.lSendID = 1;
Deliver.lMsgID = head.SeqID;
//转换网络字节id
Deliver.lMsgID.Node_Id=ntohl(Deliver.lMsgID.Node_Id);
Deliver.lMsgID.Time =ntohl(Deliver.lMsgID.Time);
Deliver.lMsgID.Sequence_Id=ntohl(Deliver.lMsgID.Sequence_Id);
Deliver.deliver = *pDeliver;
Deliver.deliver.MessageLength = ntohl(Deliver.deliver.MessageLength);
memcpy(Deliver.szMsg,pMsgData,Deliver.deliver.MessageLength ); //取信息内容
//Status_Add(Deliver); //添加到列表
Deliver_Add(Deliver); //添加到列表
}
//发送返回
Sgip_Deliver_Resp sresp={0};
sresp.Result = 0;
Sgip_SeqID lReq=head.SeqID;
//最后发送时间问题
if ( sock == m_hSocket )
{
SendFrame(sock,m_lNodeID,m_lID,m_dwEndSendTime,SGIP_DELIVER_RESP,(BYTE*)&sresp,sizeof(sresp),lReq);
}
else
{
DWORD dwEndSendTime=0;
SendFrame(sock,m_lNodeID,m_lID,dwEndSendTime,SGIP_DELIVER_RESP,(BYTE*)&sresp,sizeof(sresp),lReq);
}
return true;
}
long CSgip::Process_Report(SOCKET sock,Sgip_Head head, BYTE *pData, long lLen)
{
Sgip_Report * pReport = (Sgip_Report *)pData;
BYTE * pMsgData = pData+sizeof(Sgip_Deliver);
Sgip_SeqID lMsgID=pReport->lMsgID;
//转换网络字节id
lMsgID.Node_Id=ntohl(lMsgID.Node_Id);
lMsgID.Time =ntohl(lMsgID.Time);
lMsgID.Sequence_Id=ntohl(lMsgID.Sequence_Id);
//判断是否cmpp转接的短信内容
BOOL bExchange=false;
if ( m_pSgipExchange )
{
long lExNum=0;
/*
if ( m_bAdc ) //&& pDeliver->Registered_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;
wsprintf((char*)pDeliver->Dest_Id , "1065710055%s",szTemp ); //这类特殊的转换直接使用总端口
}
}
*/
for ( int i=0 ; i<m_lSgipExchange;i++ )
{
ULONG lExID=lMsgID.Sequence_Id/0x1000000;
if (m_pSgipExchange[i].sock != 0 && m_pSgipExchange[i].sock != INVALID_SOCKET &&
strlen(m_pSgipExchange[i].szNum)>0 &&
(lExID == m_pSgipExchange[i].lExID || lMsgID.Node_Id == m_pSgipExchange[i].lNodeID) )
{
SgipExchangeResp resp={0};
resp.lType = 1;
strcpy(resp.szNum , m_pSgipExchange[i].szNum );
resp.lExNum = lExNum; //adc特殊转发时用到
resp.lLen = lLen;
resp.lCmd = head.Command_Id;
resp.lSeq = head.SeqID;
memcpy(resp.Data , pData , lLen );
SgipExchangeResp_Add(resp);
bExchange = true;
break;
}
}
}
if ( !bExchange)
{
Sgip_Deliver_List Deliver={0};
Deliver.lSendID = 1;
Deliver.lMsgID = lMsgID;
Deliver.status = *pReport;
Status_Add(Deliver); //添加到列表
}
//发送返回
Sgip_Deliver_Resp sresp={0};
sresp.Result = 0;
Sgip_SeqID lReq=head.SeqID;
//最后发送时间问题
if ( sock == m_hSocket )
{
SendFrame(sock,m_lNodeID,m_lID,m_dwEndSendTime,SGIP_REPORT_RESP,(BYTE*)&sresp,sizeof(sresp),lReq);
}
else
{
DWORD dwEndSendTime=0;
SendFrame(sock,m_lNodeID,m_lID,dwEndSendTime,SGIP_REPORT_RESP,(BYTE*)&sresp,sizeof(sresp),lReq);
}
return true;
}
BOOL CSgip::GetDeliver(Sgip_Deliver_List &deliver)
{
EnterCriticalSection(&m_CriDeliverList); //防止冲突
//从当前点到结尾
for ( int i=m_lDeliverList ; i< SGIP_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<m_lDeliverList; 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;
}
}
m_lDeliverList = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return false;
}
BOOL CSgip::Sgip_Exit()
{
m_bInitSgip = false; //已初始化
Sgip_SeqID lSeq={0};
SendFrame(m_hSocket,m_lNodeID,m_lID,m_dwEndSendTime,SGIP_UNBIND,NULL,0,lSeq);
Stop(); //停止
return true;
}
void CSgip::UCS2ToAscii2(char *pUCS2, char *pAscii, long lSrcLen)
{
UINT nLen = 0;
for(int i = 0; i < lSrcLen/2; i++)
*((unsigned short*)pUCS2 + i) = ntohs(*((unsigned short*)pUCS2 + i));
nLen = WideCharToMultiByte(936, WC_COMPOSITECHECK,
(WCHAR*)pUCS2, lSrcLen/2, pAscii,lSrcLen, NULL, NULL);
}
BOOL CSgip::SendResp_Add(Sgip_Send_Resp resp)
{
EnterCriticalSection(&m_CriRespList); //防止冲突
//从当前点到结尾
for ( int i=m_lRespList ; i< SGIP_SMS_MAX_RESP; i++ )
{
if ( m_pRespList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pRespList[i] = resp;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lRespList; i++ )
{
if ( m_pRespList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pRespList[i] = resp;
LeaveCriticalSection(&m_CriRespList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriRespList); //防止冲突
return false;
}
BOOL CSgip::Deliver_Add(Sgip_Deliver_List Deliver)
{
EnterCriticalSection(&m_CriDeliverList); //防止冲突
//从当前点到结尾
for ( int i=m_lDeliverList ; i< SGIP_SMS_MAX_DELIVER; i++ )
{
if ( m_pDeliverList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pDeliverList[i] = Deliver;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lDeliverList; i++ )
{
if ( m_pDeliverList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pDeliverList[i] = Deliver;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return false;
}
long CSgip::Sgip_SendSms(const char * SendNo , const char * RecvNo,long Msg_Fmt,long udhi,long Msg_Length,BOOL bHandFree,const BYTE * Msg ,const char * Service_Id,long Fee_UserType,const char * FeeType, const char * FeeCode ,long Registered_Delivery,const char *ValId_Time,const char *At_Time,long lSendID,char * MsgID, BOOL bNo86)
{
if ( !m_bInitSgip )
return -1; //接口未初始化或暂时断开连接
//m_lSendID ++; //发送ID加1
m_lSendID = lSendID; //使用传过来的ID
Sgip_Send_List list={0};
list.lSendID = m_lSendID; //SendID
//取原地址类型并转换
strcpy( (char*)list.Submit.SPNumber , SendNo ); //源号码
//取目标地址类型并转换
//GetMobilePhoneTON( RecvNo , (char*)list.Submit.ChargeNumber ); //付费号码
strcpy((char*)list.Submit.ChargeNumber , "000000000000000000000" );
list.Submit.UserCount = 1; //用户数
if (bNo86)
strcpy((char*)list.Submit.UserNumber, RecvNo); //目标号码
else
GetMobilePhoneTON( RecvNo , (char*)list.Submit.UserNumber ); //目标号码
strcpy((char*)list.Submit.CorpId , m_szSgipCorpID); //企业ID
strcpy((char*)list.Submit.ServiceType , Service_Id ); //业务ID
//list.Submit.FeeType = 0x31; //计费类型,深讯平台
list.Submit.FeeType = 0x01; //计费类型,中兴平台
strcpy((char*)list.Submit.FeeValue , "000000" );//收费
strcpy((char*)list.Submit.GivenValue , "000000" );//赠送
list.Submit.AgentFlag = 0x00; //收费标志
list.Submit.MorelatetoMTFlag = 2; //引起MT消息的原因
list.Submit.Priority = 5; //优先级
strcpy((char*)list.Submit.ExpireTime , "" ); //寿命时间
strcpy((char*)list.Submit.ScheduleTime , "" ); //定时时间
list.Submit.ReportFlag = (unsigned char )Registered_Delivery; //状态报告
list.Submit.TP_pid = 0; /*协议类型缺省为0。*/
list.Submit.TP_udhi=(UCHAR)udhi; /*用于长短消息表示UserData是否是结构,0,正常,1结构*/
list.Submit.MessageCoding =0; //编码类型
list.Submit.MessageType = 0; //消息类型
list.Submit.MessageLength=0; //默认先为0
//list.Submit.MessageContent
char * pMsgSrc= (char*)Msg;
char * pMsgOK = (char*)list.Msg;
long ludhiLen=0;
if ( list.Submit.TP_udhi == 1 )
{
memcpy(pMsgOK,pMsgSrc,6); //原字节头
//list.Submit.Pk_total = pMsgOK[4]; //*相同Msg_id的消息总条数从1开始*/
//list.Submit.Pk_number = pMsgOK[5]; /*相同Msg_id的消息序号从1开始*/
pMsgSrc = pMsgSrc+6;
pMsgOK = pMsgOK+6; //采用6位数的短信分隔
ludhiLen = 6;
}
if ( Msg_Fmt==0 && Msg_Length==0 )
{
//取编码方式
//if ( isChinese((char*)pMsgSrc,strlen((char*)pMsgSrc) ) )
if ( true )
{
if ( bHandFree )
list.Submit.MessageCoding = 0x18;//UCS2编码
else
list.Submit.MessageCoding = 8;//UCS2编码
unsigned short * pusSrc = (unsigned short *)pMsgSrc;
unsigned short * pusTag = (unsigned short *)pMsgOK;
long lSrcLen = wcslen((WCHAR*)pMsgSrc);
if ( lSrcLen>(70-ludhiLen/2) ) lSrcLen=(70-ludhiLen/2);
for ( int i=0 ; i<lSrcLen ; i++ )
{
pusTag[i] = htons(pusSrc[i]);
}
//wcscpy((WCHAR*)pMsgOK,(WCHAR*)pMsgSrc);
//((WCHAR*)pMsgOK)[70]=0;
list.Submit.MessageLength = lSrcLen*2+ludhiLen;
}
else
{
if ( bHandFree )
list.Submit.MessageCoding = 0x10;//7Bit编码
else
list.Submit.MessageCoding = 0;//7Bit编码
char szBuf[1024]={0};
UCS2ToAscii((WCHAR*)pMsgSrc,szBuf);
char * pMsg = (char*)szBuf;
pMsg[160]=0; //防止短信超界
list.Submit.MessageLength = (UCHAR)(strlen((char*)pMsg)+ludhiLen);
strcpy((char*)pMsgOK,(char*)pMsg);
}
}
else
{
list.Submit.MessageCoding = (unsigned char)Msg_Fmt;//hex编码
list.Submit.MessageLength = (unsigned char)(Msg_Length/2);
HexToAscii((const char*)pMsgSrc,(char*)pMsgOK);
//memcpy(list.Msg,Msg,Msg_Length);
}
return SendSms(list); //加入发送列表
/*
//以下检测发送返回
DWORD dwTime = ::GetTickCount();
while ( ::GetTickCount()-dwTime < SGIP_SENDSMS_TIMEOUT + 5000 )
{
Sgip_Send_Resp resp={0};
if ( GetSendResp(resp) &&
resp.lSendID == m_lSendID)
{
sprintf( MsgID , "%I64u" , resp.lMsgID );
return resp.lResult; //发送成功返回cmpp的返回参数
}
Sleep_Lu( 100 );
}
return -3; //发送超时
*/
}
unsigned char CSgip::GetMobilePhoneTON(const char *pSrc, char *pOrg)
{
char szTemp[32]={0};
long lBegin = 0;
long lLen = strlen( pSrc );
unsigned lTON = 2; //2,国内号码,1,国际号码
if ( pSrc[0] == '+')
lBegin = 1; //去除"+"号
if ( pSrc[lBegin] == '0' && pSrc[lBegin+1] == '0' )
lBegin += 2; //去除"00"
strcpy( szTemp , pSrc+lBegin ); //复制去除"+"号与"00"的号码
if ( szTemp[0]=='8' && szTemp[1] =='6' ) //所有号码都要加86开头
{
strcpy( pOrg,szTemp);
}
else
{
#ifdef SGIP_3_0
sprintf( pOrg , "%s",szTemp);
#else
sprintf( pOrg , "86%s",szTemp);
#endif
}
// if ( pSrc[lBegin]=='8' && pSrc[lBegin+1] =='6' ) //因为86开头号码为国际码
// lTON = 1; //国际编码
return lTON;
}
BOOL CSgip::isChinese(const TCHAR *pSrc, long lSrcLen)
{
long lLen = lSrcLen;
if ( lLen <=0 )
lLen = _tcslen(pSrc);
#ifdef _UNICODE
for ( long i=0 ; i<lLen ; i++ )
{
if ( (BYTE)pSrc[i]>128 )
{
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 CSgip::UCS2ToAscii( const WCHAR * pUCS2 , char * pAscii)
{
long lLen = wcslen( pUCS2 );
long l = WideCharToMultiByte(CP_ACP,NULL,pUCS2,lLen, pAscii , 4096 ,NULL,NULL);
pAscii[l]=0;
return l;
}
long CSgip::AsciiToUCS2(const char *pAscii, WCHAR *pUCS2)
{
long lLen = strlen( pAscii );
long l = MultiByteToWideChar( CP_ACP,NULL,pAscii,lLen, pUCS2 , 4096 );
pUCS2[l]=0;
return l;
// szName2[l*2]=0;
/*
AsciiToHex( szName2 , pUCS2 , l*2);
ExchangeUniCode( pUCS2 );
*/
}
void CSgip::HexToAscii(const char *pszOrgRandom, char *pszDesRandom)
{
char Buf[4];
char *pDes = (char *)pszDesRandom;
char *pOrg = (char *)pszOrgRandom;
long lLen = strlen( pOrg);
long lTemp;
for( int 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 CSgip::ExchangeUniCode(char *pData)
{
char pEx[4];
long lLen = 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 CSgip::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 CSgip::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 CSgip::GetStatus(Sgip_Deliver_List &deliver)
{
EnterCriticalSection(&m_CriStatusList); //防止冲突
//从当前点到结尾
for ( int i=m_lStatusList ; i< SGIP_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 ; i<m_lStatusList; 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;
}
}
m_lStatusList = 0;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return false;
}
BOOL CSgip::Status_Add(Sgip_Deliver_List Deliver)
{
EnterCriticalSection(&m_CriStatusList); //防止冲突
//从当前点到结尾
for ( int i=m_lStatusList ; i< SGIP_SMS_MAX_STATUS; i++ )
{
if ( m_pStatusList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pStatusList[i] = Deliver;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lStatusList; i++ )
{
if ( m_pStatusList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pStatusList[i] = Deliver;
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriStatusList); //防止冲突
return false;
}
long CSgip::Sgip_Get(TCHAR *SendNo,TCHAR * RecvNo, BYTE *Msg, TCHAR *Msg_Fmt, TCHAR *Msg_Length ,long & lLongMsgRand ,long & lLongMsgAll, long & lLongMsgIndex)
{
Sgip_Deliver_List deliver={0};
if ( GetDeliver(deliver) )
{
_tcsncpy( SendNo , CA2W((char*)deliver.deliver.UserNumber),21 );
_tcsncpy( RecvNo , CA2W((char*)deliver.deliver.SPNumber),21 );
BYTE * pMsg = (BYTE *)deliver.szMsg;
long lMsgLen=deliver.deliver.MessageLength;
//if ( deliver.deliver.TP_udhi == 1 ) //判断是否长短信
//{
if ( pMsg[0]==5 && pMsg[1]==0 && pMsg[2]==3 )
{
lLongMsgRand = pMsg[3];
lLongMsgAll = pMsg[4];
lLongMsgIndex = pMsg[5];
pMsg = pMsg+6;
lMsgLen -=6;
}
if ( pMsg[0]==6 && pMsg[1]==8 && pMsg[2]==4 )
{
lLongMsgRand = pMsg[3]*100+pMsg[4];
lLongMsgAll = pMsg[5];
lLongMsgIndex = pMsg[6];
pMsg = pMsg+7;
lMsgLen -=7;
}
//}
if ( Msg_Fmt==NULL && Msg_Length==NULL ) //自动取内容
{
if (deliver.deliver.MessageCoding == 15 ) //gbk编码
{
_tcscpy((WCHAR*)Msg,CA2W((char*)pMsg));
}
else
{
if (deliver.deliver.MessageCoding & 8 ) //ucs2,要编码
{
unsigned short * pusSrc = (unsigned short *)pMsg;
unsigned short * pusTag = (unsigned short *)Msg;
long lSrcLen = lMsgLen/2;
for ( int i=0 ; i<lSrcLen ; i++ )
{
pusTag[i] = ntohs(pusSrc[i]);
}
}
else
{
if (deliver.deliver.MessageCoding & 4 )// hex编码
{
_tcscpy((TCHAR*)Msg,_T("HEX16:"));
if ( deliver.deliver.MessageLength>70 )
deliver.deliver.MessageLength=70;
AsciiToHex((const char*)pMsg,((TCHAR*)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.MessageLength); //转换成Hex编码
//memcpy(Msg,deliver.szMsg,deliver.deliver.Msg_Length);
if ( Msg_Fmt )
_stprintf( Msg_Fmt , _T("%d") , deliver.deliver.MessageCoding );
if ( Msg_Length )
_stprintf( Msg_Length , _T("%d") , deliver.deliver.MessageLength*2 );
return 0;
}
}
return -1; //没有信息
}
long CSgip::Sgip_GetReport(TCHAR *No, TCHAR *Stat, TCHAR *Done_time, TCHAR *MsgID)
{
Sgip_Deliver_List deliver={0};
if ( GetStatus(deliver) )
{
_tcscpy( No , CA2W((char*)deliver.status.UserNumber) );
//strcpy( Stat , (char*)deliver.status.Stat );
if ( deliver.status.State == 2 ) //有错误
_stprintf( Stat , _T("%d") , deliver.status.ErrorCode );
else
_tcscpy( Stat , _T("DELIVRD"));
//strcpy( Done_time , (char*)deliver.status.Done_time );
//strncpy( Done_time , (char*)deliver.status.Done_time , 10 );
_stprintf( MsgID , _T("%010u%010u%010u") , deliver.lMsgID.Node_Id,deliver.lMsgID.Time,deliver.lMsgID.Sequence_Id );
return 0;
}
return -1; //没有信息
}
BOOL CSgip::GetSgipExchangeResp(SgipExchangeResp &resp)
{
EnterCriticalSection(&m_CriSgipExchangeResp); //防止冲突
//从当前点到结尾
for ( int i=m_lSgipExchangeRespList ; i< SGIP_SMS_MAX_SGIPEXCHANGERESP; i++ )
{
if ( m_pSgipExchangeResp[i].lLen != 0 ) //其等于0时认为此位置为空
{
m_lSgipExchangeRespList = i+1;
resp = m_pSgipExchangeResp[i];
m_pSgipExchangeResp[i].lLen = 0;
LeaveCriticalSection(&m_CriSgipExchangeResp); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lSgipExchangeRespList; i++ )
{
if ( m_pSgipExchangeResp[i].lLen != 0 ) //其等于0时认为此位置为空
{
m_lSgipExchangeRespList = i+1;
resp = m_pSgipExchangeResp[i];
m_pSgipExchangeResp[i].lLen = 0;
LeaveCriticalSection(&m_CriSgipExchangeResp); //防止冲突
return true;
}
}
m_lSgipExchangeRespList = 0;
LeaveCriticalSection(&m_CriSgipExchangeResp); //防止冲突
return false;
}
BOOL CSgip::SgipExchangeResp_Add(SgipExchangeResp resp)
{
EnterCriticalSection(&m_CriSgipExchangeResp); //防止冲突
//从当前点到结尾
for ( int i=m_lSgipExchangeRespList ; i< SGIP_SMS_MAX_SGIPEXCHANGERESP; i++ )
{
if ( m_pSgipExchangeResp[i].lLen == 0 ) //其等于0时认为此位置为空
{
m_pSgipExchangeResp[i] = resp;
LeaveCriticalSection(&m_CriSgipExchangeResp); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lSgipExchangeRespList; i++ )
{
if ( m_pSgipExchangeResp[i].lLen == 0 ) //其等于0时认为此位置为空
{
m_pSgipExchangeResp[i] = resp;
LeaveCriticalSection(&m_CriSgipExchangeResp); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriSgipExchangeResp); //防止冲突
return false;
}
void CSgip::SetSgipExchangeNum(CmppExchange * pSgipExchange , long lSgipExchange)
{
m_pSgipExchange = pSgipExchange;
m_lSgipExchange = lSgipExchange;
}
long CSgip::Sgip_Recv(const char *pIP, long lPort)
{
if ( m_bRecvInit && m_hRecv_Socket!=NULL && m_hRecv_Socket!= INVALID_SOCKET )
return 0;
strcpy(m_szRecvIP , pIP );
m_lRecvPort = lPort;
//启用端口
sockaddr_in Addr; //用于构造主SOCKET
m_hRecv_Socket=socket(AF_INET,SOCK_STREAM,0);
Addr.sin_family=AF_INET;
Addr.sin_port=htons( (unsigned short)m_lRecvPort ); //初始化信息端口
Addr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(m_hRecv_Socket,(LPSOCKADDR)&Addr,sizeof(Addr))==SOCKET_ERROR)
{
//AddLogMsg(Send, "Sgip Bind端口失败" );
return -1;
}
if ( listen(m_hRecv_Socket,5)==SOCKET_ERROR )
{
//AddLogMsg(Send, "Sgip listen端口失败" );
return -2;
}
m_bQuitThread_Recv = false;
m_bRecvInit = true;
DWORD ID;
m_hThread_Recv = CreateThread( NULL , 0 , (LPTHREAD_START_ROUTINE)Sgip_Recv_Accept , (LPVOID)this , 0 , &ID );
return 0;
}
UINT CSgip::Sgip_Recv_Accept(LPVOID sParam)
{
CSgip * pSgip = (CSgip *)sParam;
while ( pSgip->m_bRecvInit && !pSgip->m_bQuitThread_Recv )
{
//接入远端的SOCKET连接
sockaddr_in sAccecpAddr; //创建子socket用到的结构
int lAccecpAddrLen=sizeof(sockaddr);
SOCKET sCli;
sCli = accept( pSgip->m_hRecv_Socket ,(struct sockaddr far *)&sAccecpAddr,&lAccecpAddrLen);
if ( sCli!=INVALID_SOCKET && sCli!=SOCKET_ERROR )
{
//CString str;
//str.Format( "Sgip 新的连接:%s:%d" , inet_ntoa(sAccecpAddr.sin_addr),inet_ntoa(sAccecpAddr.sin_addr) );
//AddLogMsg(Send, str );
Sgip_Recv_ProcessT * pSend = new Sgip_Recv_ProcessT;
pSend->p = (LPVOID)pSgip;
pSend->sock = sCli;
DWORD ID;
CreateThread( NULL , 0 , (LPTHREAD_START_ROUTINE)Sgip_Recv_Process , (LPVOID)pSend , 0 , &ID );
}
else
{
break;//停止了服务,自动退出
}
}
closesocket(pSgip->m_hRecv_Socket);
pSgip->m_hRecv_Socket = INVALID_SOCKET;
pSgip->m_bRecvInit = false;
return 0;
}
UINT CSgip::Sgip_Recv_Process(LPVOID sParam)
{
Sgip_Recv_ProcessT * pSend = (Sgip_Recv_ProcessT*)sParam;
Sgip_Recv_ProcessT Send = *pSend;
delete pSend;
CSgip * pSgip = (CSgip *)Send.p;
SOCKET sock = Send.sock;
ULONG lID=0;
DWORD dwEndSendTime=0;
BOOL bLogin=false;
Sgip_Data_Recv Drecv={0};
DWORD m_dwEndRecvTime=::GetTickCount();
long dwReCountTime=0;
DWORD dwIdleTime = 0;
while ( pSgip->m_bRecvInit && !pSgip->m_bQuitThread_Recv )
{
if ( CSgip::isSocketClose(sock) )
{
//AddLogMsg(Send, "Sgip 对端已关闭" );
break;
}
if ( CSgip::ReadFrame(sock,&Drecv) ) //判断是否有接收到新的Frame
{
m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间
//pNet->RecvFrame(Drecv); //处理接收到的帧
Sgip_Head * pHead=(Sgip_Head *)Drecv.pRecvFrame;
if ( pHead->Total_Length != Drecv.lRecvLen ) //收到错误帧,要重新来过
{
//AddLogMsg(Send, "Sgip 收到错误帧" );
break;
}
pHead->Command_Id = ntohl(pHead->Command_Id);
pHead->SeqID.Node_Id= ntohl(pHead->SeqID.Node_Id);
pHead->SeqID.Time= ntohl(pHead->SeqID.Time);
pHead->SeqID.Sequence_Id= ntohl(pHead->SeqID.Sequence_Id);
BYTE * pData = (BYTE*)(Drecv.pRecvFrame+sizeof(Sgip_Head));
long lLen = pHead->Total_Length-sizeof(Sgip_Head);
long lRet = 0;
switch( pHead->Command_Id )
{
case SGIP_BIND:
{
Sgip_Bind * pBind = (Sgip_Bind *)pData;
Sgip_Bind_Resp resp={0};
resp.Result= 0;
Sgip_SeqID lReq=pHead->SeqID;
CSgip::SendFrame(sock,0,lID,dwEndSendTime,SGIP_BIND_RESP,(BYTE*)&resp,sizeof(resp),lReq);
}
break;
case SGIP_SUBMIT:
{
}
break;
case SGIP_DELIVER:
{
lRet = pSgip->Process_Deliver(sock,*pHead,pData,lLen);
}
break;
case SGIP_REPORT:
{
lRet = pSgip->Process_Report(sock,*pHead,pData,lLen);
}
break;
case SGIP_ACTIVE_TEST:
lRet = 0;
break;
default:
break;
}
Drecv.lDataLen = 0;
delete Drecv.pRecvFrame;
Drecv.pRecvFrame = NULL;
}
//判断接收是否超时
dwIdleTime = ::GetTickCount() - m_dwEndRecvTime;
if (dwIdleTime > 2000) //2秒没收到新消息延时20毫秒
{
Sleep(20);
}
if (dwIdleTime >SGIP_ACTIVE_TIMEOUT*2 ) //接收超时,断开连接,退出接收
{
break;
}
//Sleep_Lu(5);
}
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
closesocket(sock);
return 0;
}
BOOL CSgip::Sgip_Recv_Exit()
{
if ( m_hRecv_Socket == INVALID_SOCKET || m_hRecv_Socket == NULL)
return true;
m_bQuitThread_Recv= true;
Sleep_Lu(200);
closesocket(m_hRecv_Socket);
m_hRecv_Socket = INVALID_SOCKET;
m_bRecvInit = false;
return true;
}
void CSgip::SetSendSpeed(long lSpeed)
{
if (lSpeed <= 0)
{
m_lSendInterval = 0;
m_lSendIntervalCount = 1;
m_lSendIntervalIndex = 0;
}
else
{
double dwInterval = ((double)1000 / (double)lSpeed) * 0.9f;
m_lSendInterval = (long)(dwInterval + 0.5f);
if (m_lSendInterval >= 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 CSgip::GetReportSms()
{
long lReport=0;
//从当前点到结尾
for ( int i=0 ; i< SGIP_SMS_MAX_STATUS; i++ )
{
if ( m_pStatusList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
lReport++;
}
}
return lReport;
}
CString CSgip::GetErrMsg()
{
EnterCriticalSection(&m_CriErrMsg); //防止冲突
CString strRet;
if ( m_strErrMsg.GetLength()>0 )
{
strRet = m_strErrMsg;
m_strErrMsg = CString(_T(""));
}
LeaveCriticalSection(&m_CriErrMsg); //防止冲突
return strRet;
}
void CSgip::SetErrMsg(CString str)
{
EnterCriticalSection(&m_CriErrMsg); //防止冲突
m_strErrMsg = str;
LeaveCriticalSection(&m_CriErrMsg); //防止冲突
}
BOOL CSgip::isConnectGateWay()
{
return true;
//sgip网关是短连接默认是一直都在连接
/*
if ( m_bLoginSgip == 0 )
{
return true;
}
return false;
*/
}
long CSgip::GetWFSms()
{
long lWF=0;
//从当前点到结尾
for ( int i=0 ; i< SGIP_SMS_MAX_LIST; i++ )
{
if ( m_pSendList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
lWF++;
}
}
return lWF;
}
BOOL CSgip::Sms_Get(Sgip_Send_List*& pSms)
{
EnterCriticalSection(&m_CriSendSms); //防止冲突
//从当前点到结尾
int i = 0;
for (i = m_lSendList; i < SGIP_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 CSgip::Sms_Add(Sgip_Send_List sms)
{
EnterCriticalSection(&m_CriSendSms); //防止冲突
//从当前点到结尾
int i = 0;
for (i = m_lSendList; i < SGIP_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;
}