单邮件传输协议(SMTP)是一种协议,用于在邮件服务器之间发送电子邮件和路由电子邮件。
Python提供smtplib模块,该模块定义了一个SMTP客户端会话对象,可用于使用SMTP或ESMTP侦听器守护程序向任何互联网机器发送邮件。
这是一个简单的语法,用来创建一个SMTP对象,稍后将演示如何用它来发送电子邮件 -
import smtplib smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
这里是上面语法的参数细节 -
SMTP对象有一个sendmail的实例方法,该方法通常用于执行邮件发送的工作。它需要三个参数 -
1.使用Python发送纯文本电子邮件
示例
以下是使用Python脚本发送一封电子邮件的简单方法 -
#!/usr/bin/python3 import smtplib sender = 'from@fromdomain.com' receivers = ['to@todomain.com'] message = """From: From Person <from@fromdomain.com> To: To Person <to@todomain.com> Subject: SMTP e-mail test This is a test e-mail message. """ try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message) print "Successfully sent email" except SMTPException: print "Error: unable to send email"
在这里,已经发送了一封基本的电子邮件,使用三重引号,请注意正确格式化标题。一封电子邮件需要一个From,To和一个Subject标题,与电子邮件的正文与空白行分开。
要发送邮件,使用smtpObj连接到本地机器上的SMTP服务器。 然后使用sendmail方法以及消息,从地址和目标地址作为参数(即使来自和地址在电子邮件本身内,这些并不总是用于路由邮件)。
如果没有在本地计算机上运行SMTP服务器,则可以使用smtplib客户端与远程SMTP服务器进行通信。除非您使用网络邮件服务(如gmail或Yahoo! Mail),否则您的电子邮件提供商必须向您提供可以提供的邮件服务器详细信息。以腾讯QQ邮箱为例,具体如下:
mail = smtplib.SMTP('smtp.qq.com', 587) # 端口465或587
2.使用Python发送HTML电子邮件
当使用Python发送邮件信息时,所有内容都被视为简单文本。 即使在短信中包含HTML标签,它也将显示为简单的文本,HTML标签将不会根据HTML语法进行格式化。 但是,Python提供了将HTML消息作为HTML消息发送的选项。
发送电子邮件时,可以指定一个Mime版本,内容类型和发送HTML电子邮件的字符集。
以下是将HTML内容作为电子邮件发送的示例 -
#!/usr/bin/python3 import smtplib message = """From: From Person <from@fromdomain.com> To: To Person <to@todomain.com> MIME-Version: 1.0 Content-type: text/html Subject: SMTP HTML e-mail test This is an e-mail message to be sent in HTML format <b>This is HTML message.</b> <h1>This is headline.</h1> """ try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message) print "Successfully sent email" except SMTPException: print "Error: unable to send email"
3.发送附件作为电子邮件
要发送具有混合内容的电子邮件,需要将Content-type标题设置为multipart / mixed。 然后,可以在边界内指定文本和附件部分。
一个边界以两个连字符开始,后跟一个唯一的编号,不能出现在电子邮件的消息部分。 表示电子邮件最终部分的最后一个边界也必须以两个连字符结尾。
所附的文件应该用包(“m”)功能编码,以便在传输之前具有基本的64编码。
4.发送示例
首先我们要知道用python代理登录qq邮箱发邮件,是需要更改自己qq邮箱设置的。在这里大家需要做两件事情:邮箱开启SMTP功能 、获得授权码。之后我们来看看如何更改模板代码,实现使用Python登录QQ邮箱发送QQ邮件。
注意:也可以使用其他服务商的 SMTP 访问(QQ、网易、Gmail等)。
使用QQ邮件发送邮件之前如何设置授权码,参考:
http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
4.1.发送一纯文本邮件到指定邮件
#! /usr/bin/env python #coding=utf-8 from email.mime.text import MIMEText from email.header import Header from smtplib import SMTP_SSL #qq邮箱smtp服务器 host_server = 'smtp.qq.com' #sender_qq为发件人的qq号码 sender_qq = '123123123@qq.com' #pwd为qq邮箱的授权码 pwd = '****kenbb***' ## xh**********bdc #发件人的邮箱 sender_qq_mail = '123123123@qq.com' #收件人邮箱 receiver = 'felix.com@gmail.com' #邮件的正文内容 mail_content = '你好,这是使用python登录qq邮箱发邮件的测试' #邮件标题 mail_title = 'Maxsu的邮件' #ssl登录 smtp = SMTP_SSL(host_server) #set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式 smtp.set_debuglevel(1) smtp.ehlo(host_server) smtp.login(sender_qq, pwd) msg = MIMEText(mail_content, "plain", 'utf-8') msg["Subject"] = Header(mail_title, 'utf-8') msg["From"] = sender_qq_mail msg["To"] = receiver smtp.sendmail(sender_qq_mail, receiver, msg.as_string()) smtp.quit()
执行上面代码后,登录接收邮件的邮件帐号,这里接收邮件的账号为:felix.com@gmail.com,登录 http://gmail.com 应该会看到有接收到邮件如下 -
目录内容 2
0. 修改记录 3
1. 短信概念 4
2. 短信分类 5
2.1. TEXT短信 5
2.2. PDU短信 5
3. 短信应用 6
3.1. 发送短信 6
3.1.1. TEXT短信方式 6
3.1.2. PDU短信方式 6
3.2. 编写短信 7
3.2.1. TEXT短信方式 7
3.2.2. PDU短信方式 7
3.3. 转发短信 8
3.4. 读取短信 9
3.4.1. TEXT短信方式 9
3.4.2. PDU短信方式 9
3.5. 删除短信 10
3.5.1. TEXT短信方式 10
3.5.2. PDU短信方式 11
4. PDU串分类及结构 12
4.1. SUBMIT-PDU 12
4.1.1. 结构 12
4.1.2. 说明 12
4.1.3. 举例分析 15
4.2. DELIVER-PDU 16
4.2.1. 结构 17
4.2.2. 说明 17
4.2.3. 举例分析 19
5. 短信工作过程 22
5.1. 设备之间的交互过程 22
5.2. 平台的消息处理过程 23
5.2.1. 发送短信 23
5.2.2. 接收短信 23
版本 | 日期 | 作者 | 修改内容记录 |
1.0 | 2012-08-10 | Vicent.Gao | 初始版本,讲述了短信的基本操作,及PDU串的结构 |
2.0 | 2012-08-17 | Vicent.Gao | 加入新的一章:第5章 “短信工作过程” |
短消息,即SMS,英文全称short message service,是一种使用手机发送和接收有限长度文本信息的通讯服务;
更加详细的介绍,请查看链接:
http://www.jl.10086.cn/whatsnew/newrelease/duanxin.html
在用户使用的角度看,短信共分为2类,分别是TEXT短信、PDU短信。
在写短信、发送短信时,可以选择使用TEXT短信方式,也可以选择使用PDU短信方式;
在读取短信时,可以选择使用TEXT短信方式,也可以使用PDU短信方式;
编写的短信、接收的短信,实际是以PDU短信方式存储在ME或SM中;
在发送短信时,实际是以PDU短信方式发往SCA,再由SCA转发至对方手机;
以可读的方式,编写、发送、读取短信。在编写短信、发送短信时,需要内部转换成PDU模式,才能进行存储、发送。
如:
AT+CMGR=1
+CMGR: "REC UNREAD","+8615055135325","","2012/08/10 10:56:08+32"
0123456789
OK
根据指定的PDU格式,填充必要的域,如<SCA>, <FO>,<DCS>等,不需要内部进行转换,可以直接进行存储或发送。也可以使用PDU短信方式,读取编写和接收的短信。
如:
AT+CMGR=1
+CMGR: 1,,29
0891683108501505F0040D91685150155323F50000218001016580230AB0986C46ABD96EB81C
OK
客户在使用短信功能时,可以完成发送短信、编写短信、转发短信、读取短信、删除短信的操作。
AT+CMGF=1 //设置使用TEXT短信方式
OK
AT+CSCS="GSM" //设置编辑短信时,使用的字符集
OK
AT+CMGS="15055135325" //使用CMGS发送短信给自身,此处需要填写DA,即目标地址
> 0123456789 //按<CTRL+Z>开始发送短信
+CMGS: 28 //短信已发送,MR=28,其中MR为Messge Reference,用来唯一标识一条短信
OK //短信发送成功
+CMTI: "SM",1 //接收到的短信,存储在SM中,索引号为1的位置上
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGS\CMGS_TEXT.ini
AT+CMGF=0 //设置使用PDU短信方式
OK
AT+CMGS=24 //使用CMGS发送短信给自身,此处需要填写TPDU串的长度,即PDU串中除去SCA域之后的数据长度,以Byte为单位
> 0891683108501505F011000D91685150155323F500000A0AB0986C46ABD96EB81C //按<CTRL+Z>开始发送短信
+CMGS: 29 //短信已发送,MR=29,其中MR为Messge Reference,用来唯一标识一条短信
OK //短信发送成功
+CMTI: "SM",2 //接收到的短信,存储在SM中,索引号为2的位置上
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGS\CMGS_PDU.ini
AT+CMGF=1 //设置使用TEXT短信方式
OK
AT+CSCS="GSM" //设置编辑短信时,使用的字符集
OK
AT+CMGW //使用CMGW编写短信,没有指明DA,即目标地址,也可以在命令中指明
> 0123456789 //按<CTRL+Z>开始存储短信
+CMGW: 5 //编写的短信,存储在索引号为5的位置上
OK //编写短信成功
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGW\CMGW_TEXT.ini
AT+CMGF=0 //设置使用PDU短信方式
OK
AT+CMGW=17 //使用CMGW编写短信,此处需要填写TPDU串的长度,即PDU串中除去SCA域之后的数据长度,以Byte为单位
> 0011FF00000000470AB0986C46ABD96EB81C //按<CTRL+Z>开始存储短信
+CMGW: 7 //编写的短信,存储在索引号为7的位置上
OK //编写短信成功
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGW\CMGW_PDU.ini
需要指明短信存储时使用的索引号,才能完成转发操作。由于短信在存储时,都是以PDU短信方式来进行存储的,所以此命令与使用的短信方式(TEXT或PDU)无关。
AT+CMGF=0 //设置使用TEXT短信方式
OK
AT+CSCS="GSM" //设置编辑短信时,使用的字符集
OK
AT+CMSS=7,"15055135325" //使用CMSS转发短信给自身,此短信存储在索引号为7的位置上,此处指明了DA,即目标地址
+CMSS: 30 //短信已发送,MR=29,其中MR为Messge Reference,用来唯一标识一条短信
OK //短信发送成功
+CMTI: "SM",9 //接收到的短信,存储在SM中,索引号为9的位置上
AT+CMGF=1 //设置使用PDU短信方式
OK
AT+CSCS="GSM" //设置编辑短信时,使用的字符集
OK
AT+CMSS=7,"15055135325" //使用CMSS转发短信给自身,此短信存储在索引号为7的位置上,此处指明了DA,即目标地址
+CMSS: 31 //短信已发送,MR=29,其中MR为Messge Reference,用来唯一标识一条短信
OK //短信发送成功
+CMTI: "SM",10 //接收到的短信,存储在SM中,索引号为10的位置上
注:
在TEXT短信方式、PDU短信方式下,转发同一条短信,都可以成功发送,则说明CMSS转发短信与具体采用的短信方式(使用CMGF命令设置)无关。
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMSS\CMSS.ini
使用CMGD读取单条短信,使用CMGL读取某一类别的短信。
AT+CMGF=1 //设置使用TEXT短信方式
OK
AT+CMGR=1 //使用CMGR命令,读取索引号1位置上的短信
+CMGR: "REC UNREAD","+8615055135325","","2012/08/10 10:56:08+32"
0123456789 //在TEXT短信方式下,列出的短信内容
OK
AT+CMGL=? //使用CMGL读取指定类别的短信,在TEXT短信方式下,查询CMGL命令的用法
+CMGL: ("REC UNREAD","REC READ","STO UNSENT","STO SENT","ALL") //在TEXT短信方式下,使用String方式来指明要读取短信的类别
OK
AT+CMGL="STO UNSENT" //显示所有未发送的短信
+CMGL: 3,"STO UNSENT","","", //第1条未发送短信,存储在索引号3位置上
0123456789
+CMGL: 4,"STO UNSENT","15055135325","", //第2条未发送短信,存储在索引号4位置上
0123456789
+CMGL: 5,"STO UNSENT","","", //第3条未发送短信,存储在索引号5位置上
0123456789
+CMGL: 6,"STO UNSENT","","", //第4条未发送短信,存储在索引号6位置上
0123456789
OK
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGR+CMGL\CMGR+CMGL_TEXT.ini
AT+CMGF=0 //设置使用PDU短信方式
OK
AT+CMGR=1 //使用CMGR命令,读取索引号1位置上的短信
+CMGR: 1,,29
0891683108501505F0040D91685150155323F50000218001016580230AB0986C46ABD96EB81C //在PDU短信方式下,列出的短信内容
OK
AT+CMGL=? //使用CMGL读取指定类别的短信,在PDU短信方式下,查询CMGL命令的用法
+CMGL: (0-4) //在PDU短信方式下,使用Integer方式来指明要读取短信的类别
OK
AT+CMGL=2 //显示所有未发送的短信
+CMGL: 3,2,,17 //第1条未发送短信,存储在索引号3位置上
0011FF00000000470AB0986C46ABD96EB81C
+CMGL: 4,2,,23 //第2条未发送短信,存储在索引号4位置上
0011FF0B815150155323F50000470AB0986C46ABD96EB81C
+CMGL: 5,2,,17 //第3条未发送短信,存储在索引号5位置上
0011FF00000000470AB0986C46ABD96EB81C
+CMGL: 6,2,,17 //第4条未发送短信,存储在索引号6位置上
0011FF00000000470AB0986C46ABD96EB81C
OK
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGR+CMGL\CMGR+CMGL_PDU.ini
在删除短信时,建议使用CMGD删除单条命令,使用QMGDA删除指定类别的短信。当然,使用CMGD命令的<delflag>参数,也可以删除指定类别的短信。
AT+CMGF=1 //设置使用TEXT短信方式
OK
AT+CMGD=1 //使用CMGD删除索引号1位置上的短信
OK
AT+QMGDA=? //使用QMGDA删除某一类别的短信,在TEXT短信方式下,查询QMGDA命令的用法
+QMGDA:("DEL READ","DEL UNREAD","DEL SENT","DEL UNSENT","DEL INBOX","DEL ALL") //在TEXT短信方式下,使用String方式来指明要删除短信的类别
OK
AT+QMGDA="DEL READ" //删除所有已读短信
OK
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGD+QMGDA\CMGD+QMGDA_TEXT.ini
AT+CMGF=0 //设置使用PDU短信方式
OK
AT+CMGD=1 //使用CMGD删除索引号1位置上的短信
OK
AT+QMGDA=? //使用QMGDA删除某一类别的短信,在PDU短信方式下,查询QMGDA命令的用法
+QMGDA:(1-6) //在PDU短信方式下,使用Integer方式来指明要删除短信的类别
OK
AT+QMGDA=1 //删除所有已读短信
OK
参考的QCOM Script,请见压缩包路径:
QCOM_Script\CMGD+QMGDA\CMGD+QMGDA_PDU.ini
在使用PDU短信方式,进行短信的发送、编写、读取时,对于PDU串结构的了解是很有必要的。
PDU串共有2类,分别是SUBMIT-PDU,DELIVER-PDU,各有不同的结构。
SUBMIT-PDU,是发送短信时采用的PDU串。
SUBMIT-PDU | ||||||||||||
SCA | TPDU | |||||||||||
DA | ||||||||||||
Len | Type | Addr | FO | MR | Len | Type | Addr | PID | DCS | VP | UDL | UD |
P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 | P10 | P11 | P12 | P13 |
1 | 0~1 | 0~10 | 1 | 1 | 1 | 1 | 0~10 | 1 | 1 | 1 | 1 | 0~140 |
1 ~ 12 | 2~12 |
注:
表中的第1行为 表头部分,说明表所要表达的内容;
表中的第2行为 PDU串结构中,包含有2大部分;
表中的第3行为 PDU串结构中,TPDU部分中再划分的结构;
表中的第4行为 PDU串结构中,细分的每个部分;
表中的第5行为 对PDU串结构中,细分的每个部分,进行重新编码,方便后续的描述;
表中的第6行为 PDU串结构中,细分的每个部分,编码时占用的字节数范围;
表中的第7行为 PDU串结构中,包含的地址区域,编码时占用的字节数范围;
P1区域属于SCA域的一部分,固定占有1个字节,表示SCA域的长度,实际上表示的是P2区域和P3区域共同占有的字节数。
当P1=0x00时,表示SCA域不存在,此时平台会从CSCA命令中,读取需要的短信服务中心号码。
P2区域属于SCA域的一部分,当P1=0x00时,P2区域将不存在;当P1!=0x00时,P2 区域存在,并固定占有1字节大小;
P2区域,用于表示短信服务中心号码的类型,可能取得值有:0x91(国际型),0x81(未知类型),0xA1(国内型)。
P3区域属于SCA域的一部分,当P1=0x00时,P3区域将不存在;当P1!=0x00时,P3 区域存在,其占有的字节数为:P1 – 1。
P3区域,用于存储短信服务中心的号码,此号码采用BCD编码。
P4区域固定占有1个字节,为TPDU域的第1个字节,即First Octet。P4区域用于设置PDU串的类型,及其他重要参数。
其结构如下表:
SUBMIT-PDU FO (First Octet) | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
RP | UDHI | SRR | VPF | VPF | RD | MTI | MTI |
说明如下:
[Vicent.Gao]:后续会对此段内容,针对平台中的代码,进行更加详细的描述。
P5区域固定占有1个字节,为Message Reference,用于唯一标识一条短信。
P6区域属于DA域的一部分,固定占有1个字节,表示DA域的长度,实际上表示的是P8区域含有的BCD码字符的个数。
P7区域属于DA域的一部分,固定占有1个字节,表示目标地址的类型,可能取得值有:0x91(国际型),0x81(未知类型),0xA1(国内型)。
P8区域属于DA域的一部分,当P6=0x00时,P8区域将不存在;当P6!=0x00时,P8区域存在,其占有的字节数为:P6 / 2。P8区域用于存储目的地址号码。
P9区域固定占有1个字节,为Protocol Identifier,用于标识一条短信的种类,为文本短信,还是为其他的短信,如Voice Telephone, E-Mail SMS,一般设置为0x00即可。
P10区域固定占有1个字节,为Data Coding Scheme,表示短信内容采用的编码,及短信的类别(Message Class)。
其结构如下表:
DCS (Data Coding Scheme) | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | - | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
说明如下:
一般设置为00
文本是否压缩,0表示未压缩,1表示采用GSM标准压缩。
是否指定短消息类别,0表示没有指定,1表示已指定。
指定短信内容采用的编码,00表示默认字母表,01表示8bit数据,10表示UCS编码,11表示保留。
指定短消息类别,00表示Class 0,01表示Class 1,10表示Class 2,11表示Class 3。
其中:
Class 0,直接显示到用户终端;
Class 1,短消息存储在SIM卡上;
Class 2,短消息必须存储在SIM卡上禁止直接传输到终端;
Class 3,短消息存贮在用户设备上;
平台解码方法:
smsal_decode_dcs
P11区域,固定占有1个字节,即Validiy Period,用于表示短信服务中心在收到短信后,最长可以暂存的时间,过了有效时间之后,如果这条短信仍然没有被短信服务中心转发出去,那么将会被短信服务中心丢弃。
有效时间,分为2种格式,相对格式和绝对格式,一般都采用相对格式。
相对格式的有效时间计算方法如表:
VP | 计算方法 |
00 – 8F | (VP+1)*5 分钟 从 5 分钟间隔到 12 个小时 |
90 – A7 | 12 小时 + (VP – 143)*30 分钟 |
A8 – C4 | (VP – 166) * 1 天 |
C5 – FF | (VP – 192) * 1 周 |
P12区域,固定占有1个字节,即User Data Length,表示用户数据长度。
当短信内容采用GSM-7bit编码时,其表示P13区域含有的有效字符的个数;
当短信内容采用其他编码时,如UCS2,其表示P13区域含有的字节数;
当P12=0x00时,P13区域不存在;当P12!=0x00时,P13区域存在,用于存储用户实际发送的短信内容。
P13区域最大只有140字节的空间可供利用,当短信内容采用GSM-7bit编码时,其最大可以存储140 + 140 / 7 = 160个字符;当短信内容采用UCS2编码时,其最大可以存储140 / 2 = 70个字符,如汉字字符。
SUBMIT-PDU串如下:
0891683108501505F011000D91685150155323F500000A0AB0986C46ABD96EB81C
拆分如下:
08 91 683108501505F0 11 00 0D 91 685150155323F5 00 00 0A 0A B0986C46ABD96EB81C
08 91 683108501505F0 11 00 0D 91 685150155323F5 00 00 AA 0A B0986C46ABD96EB81C
如表:
P1/SCA Len | P2/SCA Type | P3/SCA Addr | P4/FO | P5/MR |
08 | 91 | 683108501505F0 | 11 | 00 |
P6/DA Len | P7/DA Type | P8/DA Addr | P9/PID | P10/DCS |
0D | 91 | 685150155323F5 | 00 | 00 |
P11/VP | P12/UDL | P13/UD | ||
0A | 0A | B0986C46ABD96EB81C |
分析结果:
内容:08
解析:SCA域长度为8个字节,即P2区域和P3区域总共的区域有8个字节,其中P2区域固定占用1个字节,P3区域占用7个字节。
内容:91
解析:短信服务中心号码为国际型。
内容:683108501505F0
解析:短信服务中心号码为:8613800551500
内容:11
解析:此PDU类型为SUBMIT-PDU,采用相对有效期格式。
内容:00
解析:Messge Reference,即短消息发送参考号,采用默认值00。
内容:0D
解析:DA域长度为0D/02=7个字节,含有0D=14个BCD码字符,即P8区域占有7个字节,含有14个BCD码字符。
内容:91
解析:目的地址号码类型为国际型。
内容:685150155323F5
解析:目的地址号码为:8615055135325
内容:00
解析:Protocol Identifier,采用默认值00,即普通文本短消息。
内容:00
解析:Data Coding Scheme,采用默认值00,即GSM-7bit编码,Class 1类型。
内容:0A
解析:短消息在短信服务中心存储的有效时间为:(0A + 1) * 5 = 55分钟。
内容:0A
解析:由于采用GSM-7bit编码,所以此处表示P13区域内含有10个字符。
内容:B0986C46ABD96EB81C
解析:通过对GSM-7bit编码内容进行解码,得知短信内容为:0123456789
DELIVER-PDU,是接收到的短信采用的PDU串。
DELIVER-PDU | |||||||||||
SCA | TPDU | ||||||||||
OA | |||||||||||
Len | Type | Addr | FO | Len | Type | Addr | PID | DCS | SCST | UDL | UD |
P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 | P10 | P11 | P12 |
1 | 1 | 6~10 | 1 | 1 | 1 | 6~10 | 1 | 1 | 7 | 1 | 0~140 |
8~ 12 | 8~12 |
注:
表中的第1行为 表头部分,说明表所要表达的内容;
表中的第2行为 PDU串结构中,包含有2大部分;
表中的第3行为 PDU串结构中,TPDU部分中再划分的结构;
表中的第4行为 PDU串结构中,细分的每个部分;
表中的第5行为 对PDU串结构中,细分的每个部分,进行重新编码,方便后续的描述;
表中的第6行为 PDU串结构中,细分的每个部分,编码时占用的字节数范围;
表中的第7行为 PDU串结构中,包含的地址区域,编码时占用的字节数范围;
P1区域属于SCA域的一部分,固定占有1个字节,表示SCA域的长度,实际上表示的是P2区域和P3区域共同占有的字节数。
P2区域属于SCA域的一部分,固定占有1个字节,用于表示短信服务中心号码的类型,可能取得值有:0x91(国际型),0x81(未知类型),0xA1(国内型)。
P3区域属于SCA域的一部分,其占有的字节数为:P1 – 1,用于存储短信服务中心的号码,此号码采用BCD编码。
P4区域固定占有1个字节,为TPDU域的第1个字节,即First Octet。P4区域用于设置PDU串的类型,及其他重要参数。
其结构如下表:
DELIVER-PDU FO (First Octet) | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
RP | UDHI | SRI | - | - | MMS | MTI | MTI |
说明如下:
[Vicent.Gao]:后续会对此段内容,针对平台中的代码,进行更加详细的描述。
P5区域属于OA域的一部分,固定占有1个字节,表示DA域的长度,实际上表示的是P7区域含有的BCD码字符的个数。
P6区域属于DA域的一部分,固定占有1个字节,表示目标地址的类型,可能取得值有:0x91(国际型),0x81(未知类型),0xA1(国内型)。
P7区域属于DA域的一部分,其占有的字节数为:P5 / 2,用于存储发送方的号码。
P8区域固定占有1个字节,为Protocol Identifier,用于标识一条短信的种类,为文本短信,还是为其他的短信,如Voice Telephone, E-Mail SMS,一般都为0x00,即普通文本短信。
P9区域固定占有1个字节,为Data Coding Scheme,表示短信内容采用的编码,及短信的类别(Message Class)。
其结构如下表:
DCS (Data Coding Scheme) | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | - | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
说明如下:
一般设置为00
文本是否压缩,0表示未压缩,1表示采用GSM标准压缩。
是否指定短消息类别,0表示没有指定,1表示已指定。
指定短信内容采用的编码,00表示默认字母表,01表示8bit数据,10表示UCS编码,11表示保留。
指定短消息类别,00表示Class 0,01表示Class 1,10表示Class 2,11表示Class 3。
其中:
Class 0,直接显示到用户终端;
Class 1,短消息存储在SIM卡上;
Class 2,短消息必须存储在SIM卡上禁止直接传输到终端;
Class 3,短消息存贮在用户设备上;
平台解码方法:
smsal_decode_dcs
P10区域固定占有7个字节,即Serive Center Time Stamp,用于存储SCA转发该条短信的时间戳。
其结构如下表:
SCTS | ||||||
1 | 2 | 3 | 4 | 5 | 6 | 7 |
年 | 月 | 日 | 时 | 分 | 秒 | 时区 |
说明如下:
假设P10区域为:21800101658023,再拆分成:21 80 01 01 65 80 23,则表示SCTS为:12年 08月 10日 10时 56分 08秒 32时区
P11区域,固定占有1个字节,即User Data Length,表示用户数据长度。
当短信内容采用GSM-7bit编码时,其表示P12区域含有的有效字符的个数;
当短信内容采用其他编码时,如UCS2,其表示P12区域含有的字节数;
当P11=0x00时,P12区域不存在;当P11!=0x00时,P12区域存在,用于存储用户实际发送的短信内容。
P12区域最大只有140字节的空间可供利用,当短信内容采用GSM-7bit编码时,其最大可以存储140 + 140 / 7 = 160个字符;当短信内容采用UCS2编码时,其最大可以存储140 / 2 = 70个字符,如汉字字符。
DELIVER-PDU串如下:
0891683108501505F0040D91685150155323F50000218001016580230AB0986C46ABD96EB81C
拆分如下:
08 91 683108501505F0 04 0D 91 685150155323F5 00 00 21800101658023 0A B0986C46ABD96EB81C
如表:
P1/SCA Len | P2/SCA Type | P3/SCA Addr | P4/FO | P5/OA Len |
08 | 91 | 683108501505F0 | 04 | 0D |
P6/OA Type | P7/OA Addr | P8/PID | P9/DCS | P10/SCTS |
91 | 685150155323F5 | 00 | 00 | 21800101658023 |
P11/UDL | P12/UD | |||
0A | B0986C46ABD96EB81C |
分析结果:
内容:08
解析:SCA域长度为8个字节,即P2区域和P3区域总共的区域有8个字节,其中P2区域固定占用1个字节,P3区域占用7个字节。
内容:91
解析:短信服务中心号码为国际型。
内容:683108501505F0
解析:短信服务中心号码为:8613800551500
内容:04
解析:此PDU类型为DELIVER-PDU。
内容:0D
解析:OA域长度为0D/02=7个字节,含有0D=14个BCD码字符,即P7区域占有7个字节,含有14个BCD码字符。
内容:91
解析:发送方号码类型为国际型。
内容:685150155323F5
解析:发送方号码为:8615055135325
内容:00
解析:Protocol Identifier,采用默认值00,即普通文本短消息。
内容:00
解析:Data Coding Scheme,采用默认值00,即GSM-7bit编码,Class 1类型。
内容:21800101658023
解析:短消息服务中心在转发此条短信的时间戳为:2012年08月10日10时56分08秒。
内容:0A
解析:由于采用GSM-7bit编码,所以此处表示P12区域内含有10个字符。
内容:B0986C46ABD96EB81C
解析:通过对GSM-7bit编码内容进行解码,得知短信内容为:0123456789
码示例
#python3
#接口类型:互亿无线触发短信接口,支持发送验证码短信、订单通知短信等。
#账户注册:请通过该地址开通账户 http://user.ihuyi.com/?9vXc7
#注意事项:
#(1)调试期间,请用默认的模板进行测试,默认模板详见接口文档;
#(2)请使用 用户名 及 APIkey来调用接口,APIkey在会员中心可以获取;
#(3)该代码仅供接入互亿无线短信接口参考使用,客户可根据实际需要自行编写;
import urllib.parse
import urllib.request
#接口地址
url = 'http://106.ihuyi.com/webservice/sms.php?method=Submit'
#定义请求的数据
values = {
'account':'xxxxxxxx',
'password':'xxxxxxxxxxxx',
'mobile':'134xxxxxxxx',
'content':'您的验证码是:7835。请不要把验证码泄露给其他人。',
'format':'json',
}
#将数据进行编码
data = urllib.parse.urlencode(values).encode(encoding='UTF8')
#发起请求
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
res = response.read()
#打印结果
print(res.decode("utf8"))
-----------------------------------
#python2
#接口类型:互亿无线触发短信接口,支持发送验证码短信、订单通知短信等。
#账户注册:请通过该地址开通账户http://user.ihuyi.com/register.html
#注意事项:
#(1)调试期间,请使用用系统默认的短信内容:您的验证码是:【变量】。请不要把验证码泄露给其他人。
#(2)请使用 APIID 及 APIKEY来调用接口,可在会员中心获取;
#(3)该代码仅供接入互亿无线短信接口参考使用,客户可根据实际需要自行编写;
#!/usr/local/bin/python
#-*- coding:utf-8 -*-
import httplib
import urllib
host = "106.ihuyi.com"
sms_send_uri = "/webservice/sms.php?method=Submit"
#查看用户名 登录用户中心->验证码通知短信>产品总览->API接口信息->APIID
account = "用户名"
#查看密码 登录用户中心->验证码通知短信>产品总览->API接口信息->APIKEY
password = "密码"
def send_sms(text, mobile):
params = urllib.urlencode({'account': account, 'password' : password, 'content': text, 'mobile':mobile,'format':'json' })
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = httplib.HTTPConnection(host, port=80, timeout=30)
conn.request("POST", sms_send_uri, params, headers)
response = conn.getresponse()
response_str = response.read()
conn.close()
return response_str
if __name__ == '__main__':
mobile = "138xxxxxxxx"
text = "您的验证码是:121254。请不要把验证码泄露给其他人。"
print(send_sms(text, mobile))
你学会了吗?
*请认真填写需求信息,我们会在24小时内与您取得联系。