彩信协议相比于上一篇白话短信协议会稍微复杂一些git
和介绍短信协议时同样,咱们先简单介绍一下手机收到彩信的过程,实际上手机收到彩信有两个步骤,第一步会接收到彩信通知,第二步会去彩信通知中给的地址下载彩信文件github
以上第一步和咱们普通文本短信同样是是以短信协议的方式发送到手机上(wap-push),第二步则是经过通知中附带的地址去下载彩信文件(wap-wsp)app
一样,接下来经过白话的方式向你解释这个协议less
第一步既然也是短信协议,咱们先回顾一下短信协议的组成,是这个样子的:post
包含UDH和UD,那彩信通知中UDH和UD的值是什么呢?编码
先说UDH,其包含2个端口信息(wap-push:2948,wap-wsp:9200),这两个端口是IANA注册的端口,咱们后面说,如今咱们只须要知道,要存下这两个端口须要4个字节(每一个端口2字节),咱们正好有IEI为0x05
(Application port addressing scheme, 16 bit address),表示IED包含的是16位的端口信息,那咱们通知的UDH是这样的:3d
2948的16进制为0x0B84
,9200的16进制为0x23F0
,因此最后UDH就是:0x05 0x04 0x0B 0x84 0x23 0xF0
code
接着咱们再来讲UD,咱们前面提到了,咱们通知中会带上彩信文件的地址,当手机收到通知时,会去该地址下载彩信文件,因此,彩信的地址必然在咱们UD中,哪还有哪些东西须要包含在UD中呢?cdn
不知道你们有没有注意过彩信在手机中展现是什么样的呢?彩信确定会有图片、视频这些主要信息,不过还会发送人、主题、彩信大小这些信息。那在咱们通知中须要包含上面哪些信息呢,实际上以上就是咱们彩信文件所包含的所有信息,不过通知中是不须要图片、视频这些主要信息的,否则还要通知干什么呢,那剩下的就是通知中须要带上的信息了,包括发送人、主题、彩信大小。视频
好了,咱们知道了UD中须要存哪些信息,接下来,咱们就来看下UD的具体组成
老规矩,在这以前,介绍个概念
WSP(Wireless Session Protocol): 这是一种基于HTTP1.1的一种协议,有本身的编码方式
咱们前面说UDH的时候提到,有2个端口信息(wap-push, wap-wsp),这俩个端口刚好对应咱们彩信的两个过程,能够把它们当作目的地和源地,咱们UD也正是用WSP编码方式存储的,这里简单的说一下WSP是怎么编码的
WSP编码其实能够看作key-value编码,key的编码又有2种,一种能够当作是内置的key,一种是自定义的key
内置key的有对应的一个字节内容表明,自定义key会用专门的字符串编码方式进行编码,value和自定义key同样,若是是字符串会用专门的字符串编码方式进行编码,数字则会用专门的数字编码方式进行编码
咱们UD组成也包含信息头和信息体,这个信息头和信息体就不是短信中的UDH和UD了,而是WSP的信息头和信息体
信息头
WSP信息头很简单,包含一个TID和一个PDU TYPE,各占一个字节,TID不用去关心它,咱们只须要关心当pdu_type=6
时,就表示这是一个wap-push就OK了
好比,咱们假设TID=0
那么WSP头就为:0x00 0x06
信息体
这里咱们再介绍一个概念
MMSEP(Multimedia Messaging Service Encapsulation Protocol): 彩信封装协议,是基于WSP协议
MMSEP也包含信息头和信息体,还记得咱们以前说通知和彩信文件的内容差很少吗?其实彩信文件和通知相同的部分就是MMSEP的信息头,多出来的图片、视频就是MMSEP的信息体了,其实通知就是一个信息体为空的MMSEP
MMSEP信息头会指定一个content_type,content_type也是根据专门的字符串编码方式进行编码,好比彩信通知的content_type为:application/vnd.wap.mms-message
,MMSEP的content_type和普通content_type不太同样,MMSEP的content_type能带参数,并一块儿参与编码,彩信通知的content_type就带有一个参数X-Wap-Application-ID=x-wap-application:mms.ua
这里咱们简单看一下content_type结果:0x22 0x61 ... 0x00 0xAF 0x84
咱们大概解释一下这串编码,还记得前面说的WSP编码方式吗?X-Wap-Application-ID
这个key是内置的,用0xAF
表示,x-wap-application:mms.ua
一样,用0x84
表示,那再来看前面的,由于application/vnd.wap.mms-message
不是内置的key,因此得按照特殊字符串编码方式编码,第一位表示长度0x22
,后面0x61 ... 0x00
就是编码内容了(这里就省略了)
咱们接着看,MMSEP信息头里面除了咱们以前提到的发送人、主题、彩信大小外,还会有一些其它信息,咱们挨个介绍一下
version: 表示使用的WSP编码版本
message_type: 表示彩信类型
transaction_id: 表示事物ID
message_class_id: 表示彩信分类ID
expiry: 表示彩信有效期
subject: 表示标题
location: 表示彩信文件地址(咱们前面提到,WSP是基于HTTP的协议,这里能够是一个HTTP地址)
from: 表示发送人
这里咱们特别解释一下message_type,message_type表明了这个是一种什么类型的彩信,好比message_type=2
表示这是一个通知,message_type=4
表示这是一个彩信文件
那到这里,咱们的通知UD剩下的部分也知道了,就是这个样子:
这里大多数key都是内置的,我举几个例子,好比
0x8D90
0x80
表示这是version,0x90
表示值为1.0;
0x8A80
表示msg_class_id=personal;
0x8C82
表示message_type=2;
0x98
表示transaction_id,0x88
表示expiry,0x89
表示from,0x8E
表示size,0x83
表示location,0x96
表示subject;
这里没有例出的值的key,它们的值就须要用特殊的字符串或者数字编码了
到这里,咱们通知的部分就介绍完了,整个通知大概就是:0x05 0x04 0x0B 0x84 0x23 0xF0 0x00 0x06 0x22 0x61 ... 0x00 0xAF 0x84 0x8D90 0x8A80 0x8C82 0x98 ... 0x88 ... 0x89 ... 0x8E ... 0x83 ... 0x96 ...
这里补充一点,可能你也注意到了,从最终结果来看,既然咱们彩信通知和普通文本短信同样,并且咱们编码出来的东西极可能超过了短信字节的限制,那一样也会有可能出现一个通知分为多条发送的状况,这种状况下,咱们不能省略必要的信息,能作的可能就是将location(uri)缩短了
最后,咱们从协议的层面来看下通知是什么样子的:
前面咱们说通知的时候提到了,彩信文件其实就是比彩信通知多了图片、视频的信息,从协议来看就是比彩信通知(信息部分MMSEP header)多了信息体,其实信息体里就是放的图片、视频,彩信文件就是这个样子:
前面咱们已经介绍过了MMSEP header,那咱们彩信文件里只是部分header的值不一样,其它都与通知时同样的,下面我把不一样的取值给你列出来
content_type: application/vnd.wap.multipart.related
或application/vnd.wap.multipart.mixed
message_type: 以前也提到过,若是是彩信文件message_type=4
date: 表示彩信生成时间,不一样于通知的expiry,彩信文件中是date
这里就不例出彩信文件的编码结果了,内容和通知中MMSEP header部分类似,只是多了图片、视频的编码(固然一样包含其content_type);包括咱们以前提到编码方式的地方,都只是简单说明或直接给的值,没有说具体的方式,由于WSP编码仍是比较复杂的,有兴趣能够到SMSJ查看
smsj是个短彩信协议项目、有完整丰富的doc,smsj能方便的生成短彩信协议内容,具体使用方式能够查看项目地址