⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms.c

📁 短信发送软件
💻 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 + -