白话短信协议
我们都知道短信其实也是通过网络传输的,不过走的是核心网,那既然同样走的是网络,那这些数据不外乎 01010…,那手机是怎么把这串 01010… 翻译成我们看到的文字短信的呢?
其实短信协议和我们 HTTP 很相似,是基于 TCP/IP 的协议,短信协议也包含信息头和信息体,其每个部分都有规定的含义
接下来通过白话的方式向你解释这个协议,在这之前,有两个概念先介绍一下
PDU(Protocol Data Unit): 代表我们一条短信的整个数据,也叫一个包
UDH(User Data Header): 数据头
UD(User Data): 数据体
一个 PDU 包含一个 UDH 以及一个 UD,那一个 PDU 就是这个样子:
那接下来我们用个最常见的例子,也就是我们平时看到最多的普通文本短信为例子,挨个解释一下每个部分具体包含了哪些内容
UDH(User Data Header)
这儿也先介绍两个概念
IE(Information Element): 表示一个 UDH 单元
IED(IE Data): 包含一个 IE 的内容
IEL(Length of IE): 表示一个 IED 所占用的字节长度
IEI(IE Identifier): 表示一个 IE 具体代表的是什么含义
UDHL(Length 0f UDH): 表示整个 UDH 所占用的字节长度
一个 IE 包含一个 IEI 以及一个 IED 数据,那一个 IE 就是这个样子:
IEI 上面解释了,表示这个 IE 代表的是什么,IEI 有许多,我们这里就不展开说了,一个 IEI 占用一个字节,普通短信的 IEI=0x00
是最最常用的,表示是一条拼接短信(CONCATENATED),后面我们再解释什么是拼接短信
那 IED 里面有些什么东西呢,当 IEI=0x00
时,IED 包含 3 个字节,分别是 refNr,totalNumberOfSms,seqNr 各一个字节,这里先不用管具体的值是多少,我们只关心它们共占用了 3 个字节
最后我们来看 IEDL 的值,IEDL 同样占用一个字节,我们之所以需要 IEDL 的值,是因为不同的 IE,IED 是不一样的,所以需要指定 IED 的长度才能正确的读出数据,那当 IEI=0x00
时,我们知道 IED 占用了 3 个字节,所以IEDL=3
如果我们假设 refNr,totalNumberOfSms,seqNr 为0x01 0x01 0x01
,最后我们得到的一个 IE 的值就为:0x00 0x03 0x01 0x01 0x01
同 IEDL 一样,也需要 UDHL 的是来指定整个 UDH 的长度,UDHL 占用 1 个字节,所以 UDH 就是这个样子:
那假如我们只有一个 IE,那么我们的的 UDH 值就为:0x05 0x00 0x03 0x01 0x01 0x01
UD(User Data)
这儿也先介绍个概念
UDL(Length of UD): 表示一个 PDU 数据的所占用的字节长度
那一个完整的 PDU 就是这个样子:
UD 其实就是我们的短信内容了,也就是多个字节,这里同样先不用管内容具体是什么,同样如果我们假设短信内容为 4 个字节0xfe 0xff 0x00 0x61
,那我们加上上面的 UDH,其一共所占字节长度为 6,UDL 占用 1 个字节,所以UDL=10
最后得到的 PDU 值就为:0x10 0x05 0x00 0x03 0x01 0x01 0x01 0xfe 0xff 0x00 0x61
上面简单通俗的介绍了一下整个短信数据是怎么组成的,以及每个部分代表的含义,以及以普通文本短信为例子,大概说明了一下每个部分所包含的内容,那接下来我们继续介绍一下 UD 的内容是如何与文本相互转化的
在这之前,老规矩,我们再介绍一个概念
DCS(Data Coding Scheme): 表示应该以什么方式处理 UD 的数据
关于 DCS,上面说了,表示怎么处理 UD 的数据,也就是包含了 UD 怎么转化成文本的信息,其占用一个字节,可以说其中每一位 (bit) 不同,都有着不同的处理方式,虽然没有 2^8 这么多,但也不少
一个 DCS 主要包含 2 个信息,UD 编码方式(Character Set),以及短信类别(Message Class)
编码方式有 4 种(GSM 7 bit,ISO 8859-1,UCS2,reserved)
短信类别有 4 种(Class 0,Class 1,Class 2,Class 3)
以我们国内运营商为例,我们普通短信所使用的编码方式为 UCS2,短信类别为 Class 1,那 dcs 的值为0x19
,当然关于这个值肯定不是仅仅靠编码方式和短信类别得来的,我们前面说到,DCS 每一位的值都会影响到 UD 的处理,编码方式和短信类别只占用了其中 4 位,还有剩余的 4 位有其它含义,这里就不展开说了
有了 DCS,即有了编码方式,我们就能够将 UD 的字节和文本进行相互转化了,其实上面例子中 UD 的值就是英文字母 a
经过 UCS2 编码得到的字节
CONCATENATED
接下来我们说一说长文本的问题,我们都知道一条短信长度是有限制的,一般来说是 140 个字节,因为汉字一般使用 UCS2 编码,UCS2 一个字符占用 2 个字节,所以一条短信用 UCS2 编码的短信,如果超过 70 个字符,是需要拆分成多条短信的,但我们手机上却能显示超长的短信,那我们的手机又是如何处理的呢?
还记得我们前面介绍 UDH 的时候举的例子吗,当 UDH 中IEI=0x00
,表示是一条拼接短信(CONCATENATED),这个 IED 有 3 个值分别是 refNr,totalNumberOfSms,seqNr,长文本就是通过这个 IE 来识别多个短信是否是同一个短信的
解释一下这三个值的含义
refNr: 如果值相同的,则标识为同一条短信
totalNumberOfSms: 由多少条短信拼接
seqNr: 拼接短信的顺序
所以上面例子中,这三个值都为 1,就表示的是该条短信是由 1 条短信构成
这篇我们以白话的方式介绍了短信协议中的一些基本概念,短信协议的组成,以及一些常用的值,我们国内运营商所使用的协议也是基于上面所介绍的协议加入了一些各自特有的内容而形成
SMSJ
smsj 是个短彩信协议项目、有完整丰富的 doc,smsj 能方便的生成短彩信协议内容,具体使用方式可以查看项目地址