由于市场需求,飞鸽传书C/S版XEIM需要集成短信发送功能,于是进行了一番苦而累的研究,今天总算有点点成果,故来自己的网站晒晒,只是点点成果,非常有限,还希望高人能够指点一下。
本文欢迎大家转载,但请注明出处:http://www.freeeim.com/
另外,由于短信群发会造成各种各样的问题,有些是违法的,希望大家别以身试法。
开始吧!实现短信发送,必须有发送短信的设备,我用的是GSM MODEM,设备没什么特别,通电接上电脑就行了,没驱动,没设置。所有问题都在 C++ 编程上,因为设备是COM接口,所以涉及到一些COM I/O 操作,不过非常简单,因为WINDOWS 的所有I/O 都可以用File I/O API 来完成,也就是OpenFile、WriteFile、ReadFile这几个函数啦,简单吧!
第一步:发送Hello world!到你手机
先别急着写代码,我们用现有的工具(超级终端)吧。启动方法【开始】->【所有程序】->【附件】->【通讯】->【超级终端】(别怪我罗嗦,我第一次真的不知道‘超级终端’在哪里),启动后在‘连接描述’对话框的‘名称’里就随便填‘aa’就行了,没意义但必填而已,接着会出现‘连接到’对话框,这里需选一下,在‘连接时使用’选‘COM1’,因为我的 GSM MODEM 是连接在COM1的,要是你的有变动的话,可以尝试选其他,例如‘COM2’,最后按确定,出现‘COM1属性’对话框,按这个参数设置吧:每秒位数[9600],数据位[8],奇偶校验[无],停止位[1],数据流控制[无]。点确定,配置完毕,然后在超级终端的输入框输入‘AT’,如果有显示‘OK’的话,那么你成功了,GSM MODEM 与电脑连接正常。
输入以下指令来发送短信吧:
AT+CMGF=1
// 成功的话会返回‘OK’
AT+CMGS=137888888XX
成功的话会返回‘>’这个大于号,注意,手机号当然要填你自己的啦。
> Hello world!
// 输完Hello world!后,你按住CTRL 然后按 Z 字母键,这是古久以前 DOS 的 EOF 标志。
// 顺利的话,你的手机3秒内会收到短信。
如果你这里没成功,没关系,上GOOGLE或BAIDU找找“超级终端 AT指令之类的”就行了。
第二步:开始C++编程
这里需要了解“短信PDU编码解码”这个问题,可以上GOOGLE 或BAIDU查查,如果我在这里说的话,文章就会太长了,其实这问题很简单,而且我会把处理代码给出来。
PDU编码函数:
LPSTR CXSMSDlg::ChangeCODE(LPCTSTR lpText)
{
DWORD dwMinSize;
dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpText, -1, NULL, 0);
WCHAR *tmp = new WCHAR[dwMinSize];
// Convert headers from ASCII to Unicode.
MultiByteToWideChar (CP_ACP, 0, lpText, -1, tmp, dwMinSize);
char *newTmp = new char[dwMinSize*4];
memset(newTmp, 0, (dwMinSize-1)*4);
for(DWORD i=0; i<dwMinSize-1; i++)
{
char buf[5];
sprintf(buf, "%04X", tmp[i]);
strcat(newTmp, buf);
}
return newTmp;
}
// 设置短信中心
LPSTR SMS_Center_CODE(LPCTSTR lpText)
{
char *tmp = new char[20];
tmp[0] = '9';
tmp[1] = '1';
tmp[2] = '6';
tmp[3] = '8';
for (int i=0; i<6; i++)
{
tmp[i*2+4] = lpText[i*2+1];
tmp[i*2+5] = lpText[i*2];
}
tmp[14] = 'F';
tmp[16] = NULL;
int len = strlen(tmp);
char szLen[3];
sprintf(szLen, "%02d", len/2);
for(i=0; i<18; i++)
{
tmp[19-i] = tmp[17-i];
}
tmp[0] = szLen[0];
tmp[1] = szLen[1];
return tmp;
}
// 手机号码的编码
LPSTR SMS_Phone(LPCTSTR lpText)
{
char *tmp = new char[15];
tmp[0] = '6';
tmp[1] = '8';
for (int i=0; i<6; i++)
{
tmp[i*2+2] = lpText[i*2+1];
tmp[i*2+3] = lpText[i*2];
}
tmp[12] = 'F';
tmp[14] = NULL;
char *ret = new char[20+8+6];
sprintf(ret, "%s%s%s", "11000D91", tmp, "000800");
delete [] tmp;
return ret;
}
// 提交短信
void SendSMS()
{
char *pmsg =pData; //ChangeCODE(pData);
char *pnum = SMS_Phone(strTmp);
CString sendText;
int nLen = (strlen(pnum)+strlen(pmsg)) / 2;
CString strbbs;
strbbs.Format("Num Len:%d -- Msg Len%d", strlen(pnum), strlen(pmsg));
sendText.Format("AT+CMGS=%d %s%s%sa",
nLen, SMS_Center_CODE(m_strSMSCenter),
pnum, pmsg);
CString bbbb;
bbbb.Format("PDU:%d--TP-UL:%d", nLen, strlen(pmsg));
delete [] pnum;
}
注明出处:http://www.freeeim.com/