Xmpp学习记录[一]:

1 篇文章 0 订阅
1 篇文章 0 订阅

前言

前段时间产品需要实现IM功能,之前对IM的理解停留在 smack,xmpp,ejabberd 等概念。为了实现功能只能去研究xmpp,也在网上搜索了很多资料,但都无法把查询的信息串起来,正巧ejarberd服务器已经搭建完毕,于是就跑一下登录的流程,从抓包和日志去分析学习xmpp

环境

  • 1,ejarberd服务器己搭建完毕,并正常工作。
  • 2,引入了smack框架,Android项目地址:
    项目github

登录流程详解

  1. 抓包如下:
    这里写图片描述
    这里写图片描述
  2. 详细描述(对上图中换47条包,逐条分析)
packet 1,2,3:tcp 三次握手
--------------------------------------------
packet 4: client to server: 
<stream:stream 
    xmlns='jabber:client' 
    to='**.***.com' 
    xmlns:stream='http://etherx.jabber.org/streams' 
    version='1.0' 
    from='hanguojing0724@***.***.com' 
    xml:lang='en'>
标注及理解:建立tcp 连接后,client主动发第一条xmpp消息
          client 发送一个流头(发起流头),打开到server 实
          的流。
 -----------------------------------------------------

packet 5: server to client ack (TCP)
-------------------------------------------------------

packet 6: server to client xmpp 消息:
<?xml version='1.0'?>
<stream:stream 
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='716191580'
    version='1.0'
    from='**.***.com' 
    xml:lang='en'>
标注及理解:
    server 发送一个流头(应答流头)回复 client(相对发起流头,多了一个id属性:流ID)
    xmlns='jabber:client' : 内容命名空间,常见两种:jabber:client、jabber:server分别用于client-server,server-server通信,区别:jabber:client命名空间,xml流发送的节中,'to','from'属性是可选 的,而在jabber:server中,是必需的。
    xmlns:stream='http://etherx.jabber.org/streams' 流命名空间,必须由:http://etherx.jabber.org/streams来限定,否则接收流实体以一个流错误来关闭流
    id='716191580' 相对发起流头,多了id属性: id属性是流唯一标识符,称为流ID,必须是接收实体在发送应答流头时生成,并且在接收的应用内部,所生成的流ID必须是唯一的
    version='1.0' :传达了对文本定义的流相关换协议支持信号,相关协议包括:tls协商,sasl协商,流特征,流错误 ;xmpp 1.0 封装了流相关协议以及三个定义的xml节点类型的基本语义(message,presence,iq)
    xml:lang='en' // xml:lang属性,指定一个实体在该流上发送任何可读xml字符串数据的首选或缺省语言

-------------------------------------------------------          

packet 7: server to client xmpp 消息:
<stream:features>
    <register xmlns='http://jabber.org/features/iq-register'/>
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        <mechanism>PLAIN</mechanism>
        <mechanism>DIGEST-MD5</mechanism>
        <mechanism>X-OAUTH2</mechanism>
        <mechanism>SCRAM-SHA-1</mechanism>
    </mechanisms>
</stream:features> 
标注及理解:
    接收方实体在发送应答流头之后,必须发送一个<features/> 子元素,给发起方实体以声明使流协商过程继续下去的任何条件,每个条件用<features/>元素的子元素的格式,由一个不同于流命名空间和内容命名空间的命名空间来限定。<features/>可以包含一个,多个子元素,或者为空。上面消息中包含 tls ,sasl 信息。
    <starttls> 保护流的安全,使其免于被篡改和窃听,这个通道加密的方法使用传输层安全的TLS协议
    如果接收方实体包含了<required/>子元素,双方必须tls强制协商。
    在Tls协商之后,双方必须重启这个流。
    数据格式:starttls协商时,实体不能在xml元素之间发送任何空格、符号。
    如果初始化实体选择使用TLS,Starttls协商必须在SASL协商之前完成。

-------------------------------------------------------
packet 8,9: client to server tcp ack (Tcp)
-------------------------------------------------------

packet 10: client to server xmpp <starttls> 请求tls加密协商:
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'></starttls>
------------------------------------------------------

packet 11: server to client xmpp 响应tls加密协商
<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
收到该条消息后,接下来开始tls加密协商(非xmpp协议)
----------------------------------------------------

packet 12,13,14,15: tls密钥协商:
----------------------------------------------------

packet 16: client to server xmpp (wireshark 抓包是加密的) 
<stream:stream xmlns='jabber:client' 
    to='**.***.com' 
    xmlns:stream='http://etherx.jabber.org/streams' 
    version='1.0' 
    from='hanguojing0724@***.***.com' 
    xml:lang='en'>
标注及理解:
    加密协商成功后,发起实体重新发起流头创建新加密流
-------------------------------------------------------

packet 17: server to client xmpp 消息:
<?xml version='1.0'?>
<stream:stream xmlns='jabber:client' 
    xmlns:stream='http://etherx.jabber.org/streams' 
    id='2434506968' 
    from='**.***.com' 
    version='1.0' xml:lang='en'>
标注及理解:
    接收实体响应流头,分配流id(唯一标识)
------------------------------------------------------

packet 18: servet to client xmpp 消息
<stream:features>
    <register xmlns='http://jabber.org/features/iq-register'/>
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        <mechanism>PLAIN</mechanism>
        <mechanism>DIGEST-MD5</mechanism>
        <mechanism>X-OAUTH2</mechanism>
        <mechanism>SCRAM-SHA-1</mechanism>
    </mechanisms>
</stream:features>
标注及理解:
    tls加密完成后,流特征中,不在包含starttls,但还需要sasl
----------------------------------------------------

packet 19:client to server ack (tcp)
------------------------------------------------
packet 20:client to server xmpp 消息:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'>=</auth>
标注及理解:
    开始sasl协商
    发送初始化序列:从feature实体列表中选择一个方法并放在<auth/>元素的mechanism属性的值发送给接收实体,可选择包含一个初始化应答(“=”)以避免多一个来回
-------------------------------------------------------
packet 21: server to client ack (tcp):
---------------------------------------------------
packet 22: servet to client xmpp消息:<challenge>
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
 bm9uY2U9IjIzNzY0NTY0NDgiLHFvcD0iYXV0aCIsY2hhcnNldD11dGYtOCxhbGdvcml0aG09bWQ1LXNlc3M=</challenge>

packet 23:client to server xmpp消息:<response>
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
dXNlcm5hbWU9Imhhbmd1b2ppbmcwNzI0IixyZWFsbT0iaW1zLjE4NmxpZmUuY29tIixub25jZT0iMjM3NjQ1NjQ0OCIsY25vbmNlPSI0R2tOdHVwbGowSmU3NHFpWjM1Mk5hb1owSElnOUk1TyIsbmM9MDAwMDAwMDEscW9wPWF1dGgsZGlnZXN0LXVyaT0ieG1wcC9pbXMuMTg2bGlmZS5jb20iLHJlc3BvbnNlPWI2ZWYxZDM2NDExZjY4YWNiOGM2OGE2MmRlMTY4NmVmLGNoYXJzZXQ9dXRmLTg=</response>

packet 24: server to client ack 消息:

pakcet 25: server to client xmpp 消息: <challenge>
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cnNwYXV0aD04MDQ0MTdjYmQ4MGQ1ZGZlZWVlNDZlMWUwNDU0ODY2Yg==</challenge>

packet 26: client to servet xmpp消息:<response>
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'</response>

packet 27: server to client ack 消息:
packet 28: server to client xmpp消息:<sucess>
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
// 到这之后,sasl成功
标注及理解:协商sasl
        挑战和应答:
        1,s2c: <challenge/>元素
        2,c2s: <response/>元素 1,2可能多个回合
        3,s2c: <failure/>元素标识失败;<success/>元素标识成功

---------------------------------------------------

packet 29: client to server xmpp:  <stream:stream>
<stream:stream xmlns='jabber:client' 
    to='**.***.com' 
    xmlns:stream='http://etherx.jabber.org/streams' 
    version='1.0' 
    from='hanguojing0724@**.***.com' 
    id='2434506968'  // 原始流的id
    xml:lang='en'>
标注及理解:
    sasl成功后,发送一个新的流头 但是不能发送</stream>标签,因为接收方实体和初始化实体必须确定原始的流被替换成SASL协商之后的流
-------------------------------------------------------
packet 30: server to client ack 
-------------------------------------------------------
packet 31: server to client xmpp:<stream:stream>
<?xml version='1.0'?>
<stream:stream xmlns='jabber:client' 
    xmlns:stream='http://etherx.jabber.org/streams' 
    id='3878138002'  // 新流的id
    from='***.***.com' 
    version='1.0' xml:lang='en'>
标注及理解:server回复响应流头,打开流
-----------------------------------------------------
packet 32: server to client xmpp:<stream:features>
<stream:features>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
    <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
    <sm xmlns='urn:xmpp:sm:2'/>
    <sm xmlns='urn:xmpp:sm:3'/>
    <csi xmlns='urn:xmpp:csi:0'/>
</stream:features>
标注及理解:
    server 发送流特性,包含资源绑定及会话创建
-----------------------------------------------------
packet 33: client to server ack
----------------------------------------------------
packet 34: client to server xmpp: <iq>
<iq id='BycQ5-53' type='set'>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'></bind>
</iq>
标注及理解:
    SASL成功后,server发送一个新的应答流给client,then server在流特性中包含一个<bind/>元素
    server 不能包含<bind/>,直到client验证之后,通常是sasl协商成功之后。
    client 发送一个类型为set并包含了bind命名空间限定的<bind/>元素来请求服务器生成资源部分
------------------------------------------------------
packet 35: server to client ack
-------------------------------------------------------

packet 36: server to client xmpp:<iq>
<iq id='BycQ5-53' type='result'>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <jid>hanguojing0724@**.***.com/32889943041500975307369893
    </jid>
    </bind>
</iq>
标注及理解:
    server为client生成了xmpp部分,返回一个类型为result的IQ节给客户端,必须包含一个<jid/>元素来指定服务器决定的已连接资源的全JID
------------------------------------------------------
packet 37:client to servet xmpp <iq>
<iq id='BycQ5-55' type='set'>
    <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</iq>
标注及理解:
    client 请求创建一个session用于消息的收发
----------------------------------------------
packet 38: server to client ack
--------------------------------------------
packet 39: server to client xmpp : <iq>
<iq type='result' id='BycQ5-55'/>
标注及理解:
    server 回 result类型IQ 标识session建立成功
-------------------------------------------------
packet 40: client to server xmpp:<enable>
<enable xmlns='urn:xmpp:sm:3' resume='true'/>
标注及理解:
    client request  enable Stream Management
--------------------------------------------------
packet 41: server to client xmpp:<enable>
<enabled xmlns='urn:xmpp:sm:3' 
    id='g2gCbQAAABozMjg4OTk0MzA0MTUwMDk3NTMwNzM2OTg5M2gDYgAABdxiAA7hymIACspL' 
    resume='true' 
    max='300' />
标注及理解:
    resume='true' // 服务器允许恢复,设置为1 
    max='300' // 服务器指定的最大恢复时间
     登录成功
--------------------------------------------------

packet 42: client to server xmpp:<iq> 查询花名册
<iq id='BycQ5-57' type='get'>
    <query xmlns='jabber:iq:roster'>
    </query>
</iq>
------------------------------------------------------
packet 43: server to client xmpp:<iq>
 <iq 
    from='hanguojing0724@***.***.com' 
 to='hanguojing0724@***.***.com/32889943041500975307369893' 
    id='BycQ5-57' 
    type='result'>
    <query xmlns='jabber:iq:roster'>
        <item subscription='both' name='2222' jid='2222@***.***.com'>
            <group>Friends</group>
        </item>
        <item subscription='both' name='hanguojing07241@***.***.com' jid='hanguojing07241@***.***.com'/>
    </query>
 </iq>
-------------------------------------------------------
packet 44: server to client xmpp <r>
    // xmpp 0198 : 查询client是否收到了发送的stanzas
<r xmlns='urn:xmpp:sm:3'/>
------------------------------------------
packet 45:client to server ack 消息
------------------------------------------------
packet 46:client to server xmpp : <a>
client 回复收到,h值+1
<a xmlns='urn:xmpp:sm:3' h='1'/>
--------------------------------------------------
packet 47: server to client ack 消息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值