?? sms.c
字號:
/*----------------------------------------------------------------
用AT命令發送手機短信的例子
作者:江振健(網名:慕容飛云)
http://www.my66.com
E_mail:litth@yeah.net
------------------------------------------------------------------*/
#include <stdio.h>
#include <conio.h>
#include <windows.h>
/*-------------------------------------------------------------
函數名 :PduCode
功能 :生成短信的PDU編碼字符串.
參數 :cnt --短信服務中心號碼,sdt--接收號碼(對方手機號),msg--短信內容.
返回值 :經PDU編碼的字符串指針,如有錯,其內容為空.
---------------------------------------------------------------*/
char *PduCode(char *cnt,char *sdt,char *msg)
{
static unsigned char pdu[1024]="",tmp1[1024],tmp2[20];
int i,k,len_cnt=strlen(cnt),len_sdt=strlen(sdt),len_msg=strlen(msg);
memset(pdu,0,sizeof(pdu));//把存放PDU編碼的內存清零.
if(len_cnt>18||len_sdt>18||len_msg>100)return pdu;//判斷參數是否有效.
strcpy(tmp1,cnt);//把服務中心號復制到tmp1
if(len_cnt%2==1){strcat(tmp1,"F");len_cnt++;}//若服務中心號長度為奇數則追加"F".
sprintf(pdu,"%02X",(len_cnt/2)+1);//服務中心號碼長度.
if(!strncmp(cnt,"00",2))//判斷服務中心號類型.
{
strcat(pdu,"81");
}
else
{//默認短信服務中心號前有"+",如+86130200500.
strcat(pdu,"91");
}
for(k=strlen(pdu),i=0;i<len_cnt;i++,k++)
{//每兩個字節位置交換.
pdu[k]=i%2==0?tmp1[i+1]:tmp1[i-1];
}
//處理接收方手機號碼.
sprintf(tmp2,"1100%02X81",len_sdt);
strcat(pdu,tmp2);
strcpy(tmp1,sdt);
if(len_sdt%2==1)
{//若接收方手機號長度為奇數則追加"F".
strcat(tmp1,"F");
len_sdt++;
}
for(i=0,k=strlen(pdu);i<len_sdt;i++,k++)
{//每兩個字節位置交換.
pdu[k]=i%2==0?tmp1[i+1]:tmp1[i-1];
}
//處理被發送的短信的內容.
k=2*MultiByteToWideChar(CP_ACP,//轉換成UNICODE.
MB_PRECOMPOSED,msg,len_msg,(unsigned short *)tmp1,sizeof(tmp1));
sprintf(tmp2,"0008FF%02X",k);
strcat(pdu,tmp2);
for(i=0;i<k;i++)
{//將短信內容每兩個字節位置交換轉成十六進制的字符串.
sprintf(tmp2,"%02X",i%2==0?tmp1[i+1]:tmp1[i-1]);
strcat(pdu,tmp2);
}
return pdu;
}
/*-------------------------------------------------------------
函數名 :ATCommand
功能 :發送AT命令到指定的串口
參數 :hComm--串口的句柄,cmd--AT命令
返回值 :發送AT命令后收到的字符指針
---------------------------------------------------------------*/
char *ATCommand(HANDLE hComm,char *cmd)
{
DWORD readwrite=0;
static char buf[1024];
ZeroMemory(buf,sizeof(buf));
WriteFile(hComm,cmd,strlen(cmd),&readwrite,NULL);
Sleep(800);//等待調制解調器處理AT命令.
ReadFile(hComm,buf,sizeof(buf)-1,&readwrite,NULL);
printf("%s\n",buf);
return buf;
}
/*-------------------------------------------------------------
主函數
---------------------------------------------------------------*/
int main(int argc,char *argv[])
{
char buf[1024],*p,*sms,*center=NULL;
HANDLE hComm;
DCB dcb;
int len,len_center;
COMMTIMEOUTS cto = { 20, 10, 10, 10, 10 };
hComm=CreateFile("COM1",//注意:此參數視您手機與哪個串口相連而定,如COM1,COM3,COM5等.
GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
if(hComm==INVALID_HANDLE_VALUE)
{
printf("通信串口打開錯誤.");
goto Quit;
}
GetCommState(hComm,&dcb);
dcb.BaudRate = CBR_9600; // 設置波特率為9600.
dcb.ByteSize = 8; // 字節為 8位.
dcb.Parity = NOPARITY; // Parity 為 None.
dcb.StopBits = ONESTOPBIT; // 1 個停止位.
if (!SetCommState(hComm, &dcb)) {// 設置通信端口狀態.
printf("通信串口設置錯誤.");
goto Quit;
}
SetCommTimeouts(hComm,&cto);//設置超時時間.
if(!strstr(ATCommand(hComm,"AT\r"),"OK"))//判斷手機是否支持AT命令.
{
printf("通信串口未連接手機或手機不支持AT命令.\n");
goto Quit;
}
//取短信服務中心號碼.
for(p=ATCommand(hComm,"AT+CSCA?\r");*p!='\0';p++)
{//從引號間找出服務中心號,如:+CSCA: "8613010200500",145.
if(*p=='"' && center!=NULL)
{
*p='\0';break;
}
if(*p=='"' && center==NULL)
{
center=p+1;
}
}
if(center==NULL)
{
printf("找不到服務中心號碼.\n");
goto Quit;
}
sms=PduCode(center,"13026889xyz","電腦愛好者程序谷");//進行PDU編碼.
if((len=strlen(sms)/2)<=0)
{printf("PDU編碼失敗.\n");
goto Quit;
}
len_center=strlen(center);
if(len_center%2==1)
{
len_center++;
}
len-=(len_center/2)+2;//計算短信內容長度.
ATCommand(hComm,"AT+CMGF=0\r");//發送AT+CMGF=0<CR>.
sprintf(buf,"AT+CMGS=%d\r",len);
ATCommand(hComm,buf);//發送AT+CMGS=n<CR>.
ATCommand(hComm,sms);//發送經PDU編碼的字符串.
ATCommand(hComm,"\32\r");//發送(CTRL+Z+<CR>)結束.
Quit:
CloseHandle(hComm);//關閉句柄.
printf("任意鍵退出.");
getch();
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -