白话短信协议
我们都知道短信其实也是通过网络传输的,不过走的是核心网,那既然同样走的是网络,那这些数据不外乎01010...,那手机是怎么把这串01010...翻译成我们看到的文字短信的呢?
其实短信协议(gsm)和我们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能方便的生成短彩信协议内容,具体使用方式可以查看项目地址