📄 smsgw.cpp
字号:
// SMSGW.cpp: implementation of the CSMSGW class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SMSViaGateway.h"
#include "SMSGW.h"
#include "md5class.h"
#include "XMLParse.h"
#include <mmsystem.h>
#pragma comment ( lib, "winmm.lib" )
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/********************************************************************************
* Function Type : Global
* Parameter : filename - 文件名
* data - 要保存的数据
* mode - 文件打开的模式
* size - 数据大小
* nStartPos - 文件开始位置
* Return Value : >=0 - 写入文件的大小
* -1 - 写操作失败
* Description : 保存数据到文件
*********************************************************************************/
int WriteDataToFile(LPCTSTR filename,char* data,long size,LPCTSTR mode, int nStartPos=-1 )
{
ASSERT ( filename && strlen(filename) > 0 );
FILE *fp;
long retval;
fp=fopen((const char*)filename,(const char*)mode);
if ( fp!=NULL)
{
if ( nStartPos >= 0 )
{
if ( fseek ( fp, nStartPos, SEEK_SET ) != 0 )
return -1;
}
retval = (long)fwrite(data,sizeof(UCHAR),size,fp);
fclose(fp);
if(retval != size)
{
return -1;
}
else return retval;
}
else
{
return -1;
}
}
/********************************************************************************
* Function Type : Global
* Parameter : filename - 文件名
* data - 读到的数据存于此缓冲
* size - 缓冲大小
* nStartPos - 文件开始位置
* Return Value : >=0 - 读到数据的大小
* -1 - 操作失败
* Description : 从文件中读取数据
*********************************************************************************/
int ReadDataFromFile(LPCTSTR filename,char* data,long size, int nStartPos/*=-1*/)
{
FILE *fp;
long retval;
fp=fopen((const char*)filename,"rb");
if ( fp!=NULL)
{
if ( nStartPos >= 0 )
{
if ( fseek ( fp, nStartPos, SEEK_SET ) != 0 )
return -1;
}
retval = (long)fread(data,sizeof(char), size, fp);
fclose(fp);
if ( retval >= 0 ) return retval;
}
return -1;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSMSGW::CSMSGW()
: m_nPort ( 80 )
, m_bInitOK ( FALSE )
{
}
CSMSGW::~CSMSGW()
{
}
//
// 提交一个 POST 请求,返回服务器的回应
//
BOOL CSMSGW::PostRequestAndGetResponse(
LPCTSTR lpszURL, // 如:www.onlytest.net 或者 61.156.3.10
LPCTSTR lpszObjectName, // 如:/cgi-bin/modify
LPCTSTR lpszOptionalData, // 如:username=chrys&password=MyPassword
LPCTSTR lpszReferer, // 如:/modify-new.htm
OUT CString &csResponse
)
{
if ( !lpszURL || strlen(lpszURL) < 1 ||
!lpszObjectName || strlen(lpszObjectName) < 1 ||
!lpszOptionalData || strlen(lpszOptionalData) < 1 ||
!lpszReferer || strlen(lpszReferer) < 1
)
{
return FALSE;
}
BOOL bRet = FALSE;
CString csHeaders, csOptionalData = lpszOptionalData, csContentLength;
csContentLength.Format ( "Content-Length: %d\n", csOptionalData.GetLength() );
csHeaders += "POST http://";
csHeaders += lpszURL;
csHeaders += lpszObjectName;
csHeaders += " HTTP/1.1\n";
csHeaders += "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*\n";
csHeaders += "Referer: http://";
csHeaders += lpszURL;
csHeaders += lpszReferer;
csHeaders += "\n";
csHeaders += "Accept-Language: zh-cn,en-us;q=0.5\n";
csHeaders += "Content-Type: application/x-www-form-urlencoded\n";
csHeaders += "Proxy-Connection: Keep-Alive\n";
csHeaders += "User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; .NET CLR 1.0.3705; .NET CLR 1.1.4322)\n";
csHeaders += "Host: ";
csHeaders += lpszURL;
csHeaders += "\n";
csHeaders += csContentLength;
csHeaders += "Pragma: no-cache\n";
csHeaders += "\r\n";
CHttpFile* pMyHttpFile = NULL;
CHttpConnection* pConnection = NULL;
CInternetSession mySession;
try
{
mySession.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10*1000);
pConnection = mySession.GetHttpConnection(_T(lpszURL));
pMyHttpFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, lpszObjectName);
if ( pMyHttpFile->SendRequest(csHeaders,
(LPVOID)(LPCTSTR)csOptionalData, csOptionalData.GetLength()) )
{
DWORD dwStatus;
DWORD dwBuffLen = sizeof(dwStatus);
pMyHttpFile->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
if ( HTTP_STATUS_OK == dwStatus )
{
csResponse.Empty ();
CString myData;
while ( pMyHttpFile->ReadString ( myData ) )
{
csResponse += myData;
}
bRet = TRUE;
}
}
}
catch ( CInternetException* pEx )
{
bRet = FALSE;
TCHAR szErr[1024]={0};
pEx->GetErrorMessage(szErr,1024);
pEx->Delete();
}
if ( pMyHttpFile )
{
pMyHttpFile->Close();
delete pMyHttpFile;
}
if ( pConnection )
{
pConnection->Close();
delete pConnection;
}
mySession.Close();
#ifdef _DEBUG
/* { //d
CString csTempFileName = "c:\\000.html";
WriteDataToFile ( csTempFileName, csResponse.GetBuffer(0), csResponse.GetLength(), "wb" );
::ShellExecute ( NULL, "open", csTempFileName, NULL, NULL, SW_SHOWMAXIMIZED );
} //d
*/
#endif
return bRet;
}
BOOL CSMSGW::Init (
LPCTSTR lpszURL, // 网关地址,如:"61.156.3.10"
LPCTSTR lpszWebPageName_Send, // 发送短信页面名称,如:"/SendSms800"
LPCTSTR lpszWebPageName_Recv, // 发送短信页面名称,如:"/RecvSms800"
INTERNET_PORT nPort, // 端口号,如:80
LPCTSTR lpszCORPID, // 企业帐户
LPCTSTR lpszCPPW // 密码
)
{
if ( m_bInitOK ) return m_bInitOK;
if ( !lpszURL || strlen(lpszURL) < 1 ||
!lpszCORPID || strlen(lpszCORPID) < 1 ||
!lpszCPPW || strlen(lpszCPPW) < 1 ||
nPort < 1 )
{
return FALSE;
}
m_csURL = lpszURL;
m_csWebPageName_Send = lpszWebPageName_Send;
m_csWebPageName_Recv = lpszWebPageName_Recv;
m_nPort = nPort;
m_csCORPID = lpszCORPID;
m_csCPPW = lpszCPPW;
m_bInitOK = TRUE;
return m_bInitOK;
}
CString CSMSGW::CalcMD5CPPW()
{
CMD5 md5;
md5.setPlainText ( m_csCPPW );
CString csMD5CPPW = md5.getMD5Digest();
return csMD5CPPW;
}
//
// 发送短信给一个或多个手机号码
//
BOOL CSMSGW::SendSMS (
LPCTSTR lpszRecverMobileNO, // 接收短信手机号或者小灵通号码,号码以半角逗号间隔。
LPCTSTR lpszContent, // 短信内容
LPCTSTR lpszSendTime/*=NULL*/ // 发送短信的预期时间,立即发送填任务的发送写为当前时间,为NULL时表示当前时间
)
{
if ( !lpszRecverMobileNO || strlen(lpszRecverMobileNO) < 1 ||
!lpszContent || strlen(lpszContent) < 1 )
{
AfxMessageBox ( "Send gateway SMS parameter error " );
return FALSE;
}
CString csSendTime;
if ( !lpszSendTime || strlen(lpszSendTime) < 1 )
{
CTime tNow = time(NULL);
csSendTime = tNow.Format ( "%Y-%m-%d %H:%M:%S" );
}
else
{
csSendTime = lpszSendTime;
}
CString csTempData, csOptionalData, csResponse;
csTempData.Format ( "COMMANDID=%02d", SMSCMD_MULTI_SEND ); // 命令ID, 短信群发
csOptionalData += csTempData;
csTempData.Format ( "&CORPID=%s", m_csCORPID ); // 企业帐户
csOptionalData += csTempData;
csTempData.Format ( "&CPPW=%s", CalcMD5CPPW() ); // 企业密码或随机密码(MD5加密)
csOptionalData += csTempData;
csTempData.Format ( "&SOURCEADDRFLAG=%d", 1 ); // 主叫地址标识
csOptionalData += csTempData;
csTempData.Format ( "&PHONE=%s", lpszRecverMobileNO ); // 接收短信手机号或者小灵通号码,号码以半角逗号间隔。
csOptionalData += csTempData;
csTempData.Format ( "&TITLE=Task%d", time(NULL) ); // 群发任务标题
csOptionalData += csTempData;
csTempData.Format ( "&SENDTIME=%s", csSendTime ); // 发送短信的预期时间,立即发送填任务的发送写为当前时间,为NULL时表示当前时间
csOptionalData += csTempData;
csTempData.Format ( "&CONTENT=%s", lpszContent ); // 短信内容
csOptionalData += csTempData;
if ( !PostRequestAndGetResponse ( m_csURL, m_csWebPageName_Send, csOptionalData, m_csWebPageName_Send, csResponse ) )
return FALSE;
if ( csResponse.Find ( "ERROR", 0 ) >= 0 )
{
AfxMessageBox ( csResponse );
return FALSE;
}
return TRUE;
}
//
// 短信接收
// 服务器将根据企业请求回复一个xml文件
//
BOOL CSMSGW::ReceiveSMS(OUT CString &csResponse)
{
CString csTempData, csOptionalData;
csResponse.Empty ();
csTempData.Format ( "COMMANDID=%02d", SMSCMD_RECEIVE ); // 命令ID, 短信接收
csOptionalData += csTempData;
csTempData.Format ( "&CORPID=%s", m_csCORPID ); // 企业帐户
csOptionalData += csTempData;
csTempData.Format ( "&CPPW=%s", CalcMD5CPPW() ); // 企业密码或随机密码(MD5加密)
csOptionalData += csTempData;
if ( !PostRequestAndGetResponse ( m_csURL, m_csWebPageName_Recv, csOptionalData, m_csWebPageName_Recv, csResponse ) )
return FALSE;
if ( csResponse.Find ( "ERROR", 0 ) >= 0 )
{
AfxMessageBox ( csResponse );
return FALSE;
}
return TRUE;
}
//
// 接收短信,返回接收到短信的条数,失败返回-1
//
int CSMSGW::ReceiveSMS(OUT CStringArray &StrAry_SenderMobileNO, OUT CStringArray &StrAry_SMSContent, OUT CStringArray &StrAry_RecvTime)
{
StrAry_SenderMobileNO.RemoveAll ();
StrAry_SMSContent.RemoveAll ();
StrAry_RecvTime.RemoveAll ();
CString csResponse;
BOOL bRet = FALSE;
bRet = ReceiveSMS(csResponse);
if ( !bRet ) return -1;
CXMLParse XMLParse;
if ( !XMLParse.Load ( csResponse, FALSE ) )
return -1;
// 获取消息状态
bRet = XMLParse.GoTo_Child ();
if ( !bRet ) return FALSE;
CString csMsgStatus = XMLParse.GetElementValue();
if ( csMsgStatus != "MESSAGE" ) return 0;
BOOL bSuccess = FALSE;
// 依次处理所有消息
for ( int i=1; XMLParse.GoTo_ParallelNode(i); i++ )
{
if ( XMLParse.GoTo_Child () )
{
CString csPhoneNO, csSMSContent, csRecvTime;
for ( int ii=1; XMLParse.GoTo_ParallelNode(ii); ii++ )
{
TRACE ( "\n---------------------------------------------------\n" );
TRACE ( "GetElementName : %s\n", XMLParse.GetElementName() );
TRACE ( "GetElementValue : %s\n", XMLParse.GetElementValue() );
CString csElementName = XMLParse.GetElementName( &bSuccess );
if ( csElementName == "PHONE" )
{
csPhoneNO = XMLParse.GetElementValue( &bSuccess );
}
else if ( csElementName == "CONTENT" )
{
csSMSContent = XMLParse.GetElementValue( &bSuccess );
}
else if ( csElementName == "RECVTIME" )
{
csRecvTime = XMLParse.GetElementValue( &bSuccess );
csRecvTime = csRecvTime.Left ( 19 );
}
}
if ( !csPhoneNO.IsEmpty() && !csSMSContent.IsEmpty() && !csRecvTime.IsEmpty() )
{
StrAry_SenderMobileNO.Add ( csPhoneNO );
StrAry_SMSContent.Add ( csSMSContent );
StrAry_RecvTime.Add ( csRecvTime );
// 播放声音提醒新短信已收到
char szWindowDir[MAX_PATH] = {0};
GetWindowsDirectory ( szWindowDir, sizeof(szWindowDir) );
if ( strlen(szWindowDir) > 0 && szWindowDir[strlen(szWindowDir)-1] != '\\' )
strncat ( szWindowDir, "\\", sizeof(szWindowDir) );
strncat ( szWindowDir, "Media\\notify.wav", sizeof(szWindowDir) );
PlaySound ( szWindowDir, NULL, SND_FILENAME|SND_ASYNC );
}
XMLParse.GoTo_Parent ();
}
}
ASSERT ( StrAry_SenderMobileNO.GetSize() == StrAry_SMSContent.GetSize() && StrAry_SMSContent.GetSize() == StrAry_RecvTime.GetSize() );
return StrAry_SenderMobileNO.GetSize();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -