最近在做的系统需要集成手机群发功能,在网上找了很多例子,没有几个能用的,于是只得自己写,初步调试通过,发上来与大家分享
这里采用的是直接通过COM口对GSMModem 发送AT指令的方式进行短信发送的,由于GSMModem发送短信有两种方式,一种是Text文本形式,另一种是PDU编码形式,Text文本形式只能发送英文短信,如果需要发送中文或其他语言短信,只能通过PDU编码形式发送,所以我下面的例子也是采用PDU形式,PDU形式需要对发送内容进行编码,我将其写成了一个类,供大家调用
//此类负责发送内容的编码,将短信中心 messagecenternumber,接收方的号码:phonenumber,以及短信内容 messagecontent填写清楚后,调用EncodeSendContent方法返回编码后的文本,直接可以进行发送
using System;
using System.Collections.Generic;
using System.Text;
namespace GSMMode
{
class CEncodingPDU
{
/// <summary>
/// 发送状态
/// </summary>
public enum MsgSendStatus
{
提醒=1,
不提醒=2
}
public MsgSendStatus MsgSendState=MsgSendStatus.提醒;
public string MessageCenterNumber;
public string PhoneNumber;
public string MessageContent;
public string nLength; //要发送内容的长度,由两部分组成,接收手机号加上要发送的内容
/// <summary>
/// 短信内容编码
/// </summary>
/// <param name="srvContent"></param>
/// <returns></returns>
private string EncodeContent()
{
Encoding encodingUTF = System.Text.Encoding.BigEndianUnicode;
string s = null;
byte[] encodedBytes = encodingUTF.GetBytes(MessageContent);
for (int i = 0; i < encodedBytes.Length; i++)
{
s += BitConverter.ToString(encodedBytes, i, 1);
}
s = String.Format("{0:X2}{1}", s.Length / 2, s);
return s;
}
/// <summary>
/// 短信中心编码
/// </summary>
/// <param name="srvCenterNumber"></param>
/// <returns></returns>
private string EncodeMessageCenter()
{
string s = null;
string centernumber = MessageCenterNumber.IndexOf("+86") == -1 ? "86" + MessageCenterNumber : MessageCenterNumber.Substring(1, MessageCenterNumber.Length - 1);
int nLength = centernumber.Length;
for (int i = 1; i < nLength; i += 2) //奇偶互换
{
s += centernumber[i];
s += centernumber[i - 1];
}
if (!(nLength % 2 == 0)) //是否为偶数,不是就加上F,并对最后一位与加上的F位互换
{
s += 'F';
s += centernumber[nLength - 1];
}
s = String.Format("91{0}", s); //加上91,代表短信中心类型为国际化
s = String.Format("{0:X2}{1}", s.Length / 2, s); //编码后短信中心号长度,并格式化成二位十六制
return s;
}
/// <summary>
/// 电话号码编码
/// </summary>
/// <param name="srvNumber"></param>
/// <returns></returns>
private string EncodePhoneNumber()
{
string centernumber = PhoneNumber.IndexOf("+86") == -1 ? "86" + PhoneNumber : PhoneNumber.Substring(1, PhoneNumber.Length - 1);
string s = null;
int nLength = centernumber.Length;
for (int i = 1; i < nLength; i += 2) //将奇数位和偶数位交换
{
s += centernumber[i];
s += centernumber[i - 1];
}
if (!(nLength % 2 == 0)) //是否为偶数,不是就加上F,并对最后一位与加上的F位互换
{
s += 'F';
s += centernumber[nLength - 1];
}
return s;
}
/// <summary>
/// pdu发送内容编码
/// </summary>
/// <param name="strCenterNumber"></param>
/// <param name="strNumber"></param>
/// <param name="strSMScontent"></param>
/// <returns></returns>
public string EncodeSendContent()
{
string tmpstr="";
switch (MsgSendState)
{
case MsgSendStatus.提醒:
{
tmpstr = "31000D91";
break;
}
case MsgSendStatus.不提醒:
{
tmpstr = "11000D91";
break;
}
}
if (tmpstr != "")
{
string s = String.Format("{0}{1}{2}000800{3}", EncodeMessageCenter(), tmpstr, EncodePhoneNumber(), EncodeContent());
nLength = String.Format("{0:D2}", (s.Length - EncodeMessageCenter().Length) / 2); //获取短信内容加上手机号码长度
return s;
}
else
{
throw new Exception("没有设置是否发送提醒");
}
}
}
}
//此类为通讯类,负责将编码后的文本发送到接收方手机
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
namespace GSMMode
{
public class CCOMOperation
{
public class ReceivedDataEventArgs : EventArgs
{
public ReceivedDataEventArgs(SerialPort Serial)
{
TargetSerial = Serial;
}
public SerialPort TargetSerial;
}
public static readonly string Key_CTRLZ = "/x1A";
public static readonly string Key_ENTER = "/r";
private SerialPort COMConnector;
public delegate void EventRecivedMessage(object serder, ReceivedDataEventArgs e);
public event EventRecivedMessage RecivedMessage = null;
public CCOMOperation(string COMPortName)
{
COMConnector=new SerialPort(COMPortName);
COMConnector.DataReceived += new SerialDataReceivedEventHandler(COMConnector_DataReceived);
}
void COMConnector_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RecivedMessage(sender,new ReceivedDataEventArgs(COMConnector));
}
/// <summary>
/// 打开COM端口
/// </summary>
/// <returns></returns>
public bool OpenComConn()
{
if (!COMConnector.IsOpen)
{
COMConnector.Open();
}
return COMConnector.IsOpen;
}
/// <summary>
/// 关闭COM端口
/// </summary>
/// <returns></returns>
public bool CloseComConn()
{
COMConnector.Close();
return !COMConnector.IsOpen;
}
public bool SendCommand(string Command)
{
Console.WriteLine("SendMessage:" + Command);
COMConnector.Write(Command);
return true;
}
}
}
//具体调用代码:
CCOMOperation TestCom = new CCOMOperation("COM3");
CEncodingPDU test = new CEncodingPDU();
test.MessageCenterNumber ="13800100500"
test.MessageContent = "测试短信";
test.MsgSendState = CEncodingPDU.MsgSendStatus.提醒;
test.PhoneNumber ="18888888888";
string MessageContent = test.EncodeSendContent();
string MessageLen = test.nLength;
TestCom.OpenComConn();
TestCom.SendCommand("at+cmgf=0"+CCOMOperation.Key_ENTER);//设置短信发送方式,0为pdu形式,1为文本形式
TestCom.SendCommand("at+cmgs=" + MessageLen + CCOMOperation.Key_ENTER);//设定消息长度,这个直接取test.nLength即可,算法已经封装好
TestCom.SendCommand(MessageContent + CCOMOperation.Key_CTRLZ);//发送短信内容,正常的话已经发出短信了
这只是简单的例子而已,不过足以起到抛砖引玉的作用了,其中难免有遗漏或错误,各位看官海涵