给大家帖一段原来我用C++Builder做的发送SMS的程序片断吧,当时是用的GSM Module,并且使用了控件COMPort。
// 发送文本格式信息的命令串
const char szTextCmd1[]="AT+CMGF=1/r";
const char szTextCmd2[]="AT+CSMP=4,167,0,%d/r";
const char szTextCmd3[]="AT+CMGS=/"%s/"/r";
const char szTextCmd4[]="%s/x1A";
// 发送PDU格式信息的命令串
const char szPDU1[]="AT+CMGF=0/r";
const char szPDU2[]="AT+CMGS=%d/r";
const char szPDU3[]="%02X81%s1100%02X81%s0008A7%02X%s/x1A";
/*-------------------------------------------------------------------
TSMS::Send
发送短信息
参数:
p_strDestAddr —— 目标地址
p_strMsg —— 要发送的短信息
p_bUniCode —— 是否为中文
返回值:
S_OK —— 成功发送
E_FAIL —— 发送不成功
E_POINTER —— m_cpComPort指针为空,无法进行端口操作
备注:
类成员 m_eErrorCode 中包含了出错代码。
-------------------------------------------------------------------*/
HRESULT TSMS::Send( AnsiString p_strDestAddr, AnsiString p_strMsg, bool p_bUniCode )
{
if(m_cpComPort==NULL) return E_POINTER;
if(!m_cpComPort->Connected)
{
m_eErrorCode = E_SMS_NOT_CONNECTED;
if(OnError!=NULL) OnError();
return E_FAIL;
}
m_bSending = true;
if(OnBeforeSend!=NULL) // 激活消息将发送事件
OnBeforeSend( p_strDestAddr, p_strMsg, p_bUniCode );
TDateTime dtStartTime = Now();
HRESULT hr = S_OK;
m_eErrorCode = E_SMS_NOERROR;
if(p_bUniCode)
{ // 发送中文短信息
hr = SendPDUMessage(p_strDestAddr, p_strMsg );
}
else
{ // 发送英文短信息
hr = SendTextMessage(p_strDestAddr, p_strMsg );
}
if(hr!=S_OK)
{
if(m_eErrorCode == E_SMS_NOERROR)
m_eErrorCode = E_SMS_Send;
if(OnError!=NULL) OnError();
}
if((hr==S_OK)&&(OnAfterSend!=NULL)) // 激活消息已发送事件
{
TDateTime dtElapsedTime = Now() - dtStartTime;
OnAfterSend( p_strDestAddr, p_strMsg, p_bUniCode, dtStartTime, dtElapsedTime );
}
m_bSending = false;
return hr;
}
/*-------------------------------------------------------------------
TSMS::SendTextMessage
发送文本短信息
参数:
p_strDestAddr —— 目标地址
p_strMsg —— 要发送的短信息
返回值:
S_OK —— 成功发送
E_FAIL —— 发送不成功
E_POINTER —— m_cpComPort指针为空,无法进行端口操作
TYPE_E_IOERROR —— 端口读写错误
备注:
类成员 m_eErrorCode 中包含了出错代码。
-------------------------------------------------------------------*/
HRESULT TSMS::SendTextMessage( AnsiString p_strDestAddr, AnsiString p_strMsg )
{
AnsiString Str;
TStringList *slResponse = new TStringList;
int nIndex;
int nOK = slResponse->Add("OK");
int nError = slResponse->Add("ERROR");
// Set message format to TEXT MODE
// 设置消息格式为文本格式
Str.sprintf( szTextCmd1);
nIndex = WriteStrToComPort( Str, slResponse, 5000 );
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
if(m_pstrlResponse->Count==0)
{ // 返回错误
m_eErrorCode = E_SMS_NO_DEVICE;
if(OnError!=NULL) OnError();
delete slResponse;
return E_FAIL;
}
// Set Text Mode Parameters
// 设置文本格式参数
Str.sprintf( szTextCmd2, 0);
nIndex = WriteStrToComPort( Str, slResponse, 5000 );
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
int nPrompt = slResponse->Add("> ");
// Set destination address
// 设置目标地址
Str.sprintf( szTextCmd3, p_strDestAddr );
nIndex = WriteStrToComPort( Str, slResponse, 5000 );
slResponse->Delete(nPrompt);
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
if(m_pstrlResponse->Count==0)
{ // 返回错误
m_eErrorCode = E_SMS_NO_DEVICE;
if(OnError!=NULL) OnError();
delete slResponse;
return E_FAIL;
}
// Send the message , ended with ^Z ( ASCII 26 )
// Limit English message length to MAX_MSGENLEN
// 发送消息
int nSMCError = slResponse->Add("CMS ERROR");
Str.sprintf( szTextCmd4, p_strMsg.SubString(1, MAX_MSGENLEN) );
nIndex = WriteStrToComPort( Str, slResponse, 8000 );
slResponse->Delete(nSMCError);
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nSMCError)
{
delete slResponse;
m_eErrorCode = E_SMS_SMCERROR;
return E_FAIL;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
if(m_pstrlResponse->Count==0)
{ // 返回错误
m_eErrorCode = E_SMS_NO_DEVICE;
if(OnError!=NULL) OnError();
delete slResponse;
return E_FAIL;
}
delete slResponse;
return S_OK;
}
//-------------------------------------------------------------------
/*-------------------------------------------------------------------
TSMS::SendPDUMessage
发送PDU短信息
参数:
p_strDestAddr —— 目标地址
p_strMsg —— 要发送的短信息
返回值:
S_OK —— 成功发送
E_FAIL —— 发送不成功
E_POINTER —— m_cpComPort指针为空,无法进行端口操作
TYPE_E_IOERROR —— 端口读写错误
备注:
类成员 m_eErrorCode 中包含了出错代码。
-------------------------------------------------------------------*/
HRESULT TSMS::SendPDUMessage( AnsiString p_strDestAddr, AnsiString p_strMsg )
{
AnsiString TP_SC;
// SM Center 服务中心地址
int iSC;
// SM Center Address Length 服务中心地址长度
AnsiString TP_DA;
// Destination Address 目标地址
int iDA;
// Destination Address Length 目标地址长度
AnsiString TP_MSG;
// Message to Send 要发送的短信息
int iMSG;
// Message Length 短信息长度
int iTotal;
// Total Length 数据长度
AnsiString Str;
// Convert chinese message to UNICODE (UTF-16)
// 将中文信息转换为 UNICODE
Byte wszBuff[MAX_MSGLEN];
ZeroMemory(wszBuff, MAX_MSGLEN);
iMSG = MultiByteToWideChar( CP_ACP, 0, p_strMsg.c_str(), -1, (wchar_t*)wszBuff, MAX_MSGLEN ) -1 ;
// Limit Chinese message length to MAX_MSGCHLEN
// 限制中文信息的长度
if(iMSG>MAX_MSGCHLEN) iMSG=MAX_MSGCHLEN;
iMSG*=2;
{ // Reverse the high and low bytes of the UNICODE
// 将UNICODE 的高低字节反转并转换成字符串
AnsiString ts;
for(int i=0;i<iMSG;i+=2)
{
ts.sprintf("%02X%02X",wszBuff[i+1],wszBuff);
TP_MSG+=ts;
}
}
// Reverse the high and low bytes of the SM Center
// And retrieve the length of SM Center Address
// 将服务中心的地址高低字节反转,并取得其长度
TP_SC=ByteReverseString(m_strSMCenter,&iSC);
iSC++;
// Reverse the high and low bytes of the Destination Address
// And retrieve the length of Destination Address Address
// 将目标地址高低字节反转,并取得其长度
TP_DA=ByteReverseString(p_strDestAddr);
iDA=p_strDestAddr.Length();
// 计算出数据总长
iTotal = ((iDA+1)/2) + iMSG + 8;
int nIndex;
TStringList *slResponse = new TStringList;
int nOK = slResponse->Add("OK");
int nError = slResponse->Add("ERROR");
// Set message format to PDU MODE
// 将信息格式设为PDU格式
Str.sprintf( szPDU1 );
nIndex = WriteStrToComPort( Str, slResponse, 5000 );
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
if(m_pstrlResponse->Count==0)
{ // 返回错误
m_eErrorCode = E_SMS_NO_DEVICE;
if(OnError!=NULL) OnError();
delete slResponse;
return E_FAIL;
}
// Set PDU length
// 设置PDU的长度
int nPrompt = slResponse->Add("> ");
Str.sprintf( szPDU2, iTotal );
nIndex = WriteStrToComPort( Str, slResponse, 5000 );
slResponse->Delete(nPrompt);
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
if(m_pstrlResponse->Count==0)
{ // 返回错误
m_eErrorCode = E_SMS_NO_DEVICE;
if(OnError!=NULL) OnError();
delete slResponse;
return E_FAIL;
}
// Send PDU
// 发送PDU数据
int nSMCError = slResponse->Add("CMS ERROR");
Str.sprintf( szPDU3, iSC, TP_SC, iDA, TP_DA, iMSG, TP_MSG);
nIndex = WriteStrToComPort( Str, slResponse, 8000 );
slResponse->Delete(nSMCError);
if(nIndex==TYPE_E_IOERROR)
{
delete slResponse;
return nIndex;
}
if(nIndex==nSMCError)
{
delete slResponse;
m_eErrorCode = E_SMS_SMCERROR;
return E_FAIL;
}
if(nIndex==nError)
{
delete slResponse;
return E_FAIL;
}
if(m_pstrlResponse->Count==0)
{ // 返回错误
m_eErrorCode = E_SMS_NO_DEVICE;
if(OnError!=NULL) OnError();
delete slResponse;
return E_FAIL;
}
delete slResponse;
return S_OK;
}
/*-------------------------------------------------------------------
TSMS::WriteStrToComPort
端口输出
参数:
p_strString —— 输出数据
p_pstrlResponse —— 期望的响应字符串列表
p_lMilliseconds —— 超时时间
返回值:
E_FAIL —— 打开不成功
E_POINTER —— m_cpComPort指针为空,无法进行端口操作
TYPE_E_IOERROR —— 端口读写错误
其他返回值参见 WaitForResponse 。
备注:
类成员 m_eErrorCode 中包含了出错代码。
-------------------------------------------------------------------*/
DWORD TSMS::WriteStrToComPort(AnsiString p_strString, TStringList * p_pstrlResponse, DWORD p_lMilliseconds)
{
if(m_cpComPort==NULL) return E_POINTER;
if(!m_cpComPort->Connected)
{
// 设备没有连接,出错返回
m_eErrorCode = E_SMS_NOT_CONNECTED;
if(OnError!=NULL) OnError();
return E_FAIL;
}
m_csResponse->Enter();
m_pstrlResponse->Clear();
m_csResponse->Leave();
try
{
m_cpComPort->WriteStr(p_strString);
}
catch( ... )
{
// 端口读写错误
m_eErrorCode = E_SMS_PORT_IO;
if(OnError!=NULL) OnError();
return TYPE_E_IOERROR;
}
return WaitForResponse( p_pstrlResponse, p_lMilliseconds );
// 等待响应
}