项目中需要用到openfire的文件传输,但是客户端使用flex,官方提供的xiff包中并没有封装文件传输的功能,没办法,研究了几天,在google和官方smock源码的帮助下终于实现了xiff下的文件传输,在这里做个总结。
openfire服务器是基于xmpp协议的,XMPP支持两种文件流传输协议,SOCKS5 Bytestreams和 In-Band Bytestreams,SOCKS5是直接发送二进制流,而IBB是将文件转成base64码进行然后用message的形式进行传输,我这里仅实现了SOCKS5的文件代理传输。
SOCKS5文件传输需要用到两个协议,XEP-0065和XEP-0096
XEP-0096定义文件传输协议,提供了一个模块化框架使能交换被传输文件的信息以及参数的协商,也就是在传输文件之前协商将要传输的文件信息。
XEP-0065定义SOCKS5流传输标准协议,提供用于在任意两个XMPP用户之间建立字节流并进行文件传输。
根据我的理解,文件传输的过程分为协商,建立socks5连接,二进制传输这三个阶段
协商的过程最复杂,然后是建立连接,传输就比较简单,下面一个一个来讲
协商包括初始方、目标方、代理方,初始方就是发送文件方,目标方即文件接收方,代理方是socks5代理服务器,
协商过程就是三方互相发送xml来交换信息的过程,通俗点就是三个人沟通一下传什么文件和怎么传文件。
首先遵循XMP-0096协议,初始方给目标方发送包含文件信息的xml
<iq to="android@192.168.1.113/Spark 2.6.3" type="set" id="iq_13" from="iphone@192.168.1.113/xiff">
<si profile="http://jabber.org/protocol/si/profile/file-transfer" mime-type="text/plain" id="82B0C697-C1DE-93F9-103E-481C8E7A3BD8" xmlns="http://jabber.org/protocol/si">
<feature xmlns="http://jabber.org/protocol/feature-neg">
<x xmlns="jabber:x:data" type="form">
<field var="stream-method" type="list-single">
<option><value>http://jabber.org/protocol/bytestreams</value></option>
<option><value>http://jabber.org/protocol/ibb</value></option>
</field>
</x>
</feature>
<file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="img0545.png" size="152443"><desc>send</desc></file>
</si>
</iq>
目标方接收到信息后发送回执,表示同意接收文件
<iq id="iq_13" to="iphone@192.168.1.113/xiff" from="android@192.168.1.113/Spark 2.6.3" type="result">
<si xmlns="http://jabber.org/protocol/si">
<feature xmlns="http://jabber.org/protocol/feature-neg">
<x xmlns="jabber:x:data" type="submit">
<field var="stream-method">
<value>http://jabber.org/protocol/bytestreams</value>
<value>http://jabber.org/protocol/ibb</value>
</field>
</x>
</feature>
</si>
</iq>
这时进入XEP-0065协议阶段
初始方给服务器发送信息,请求提供代理服务器
<iq id="iq_15" type="get"><query xmlns="http://jabber.org/protocol/disco#items" /></iq>
服务器回复信息,告知可用的代理
<iq type="result" id="iq_15" to="iphone@192.168.1.113/xiff">
<query xmlns="http://jabber.org/protocol/disco#items">
<item jid="proxy.192.168.1.113" name="Socks 5 Bytestreams Proxy"/>
<item jid="pubsub.192.168.1.113" name="Publish-Subscribe service"/>
<item jid="conference.192.168.1.113" name="公共房间"/>
<item jid="search.192.168.1.113" name="User Search"/>
</query>
</iq>
这里选择name=“Socks 5 Bytestreams Proxy”的代理,初始方给这个代理发送信息获取代理连接信息
<iq id="iq_17" to="proxy.192.168.1.113" type="get"><query xmlns="http://jabber.org/protocol/bytestreams" /></iq>
代理方回复信息,告知初始方代理的jid、IP、端口等信息
<iq type="result" id="iq_17" from="proxy.192.168.1.113" to="iphone@192.168.1.113/xiff">
<query xmlns="http://jabber.org/protocol/bytestreams">
<streamhost jid="proxy.192.168.1.113" host="192.168.1.113" port="7777"/>
</query>
</iq>
初始方收到代理信息后将代理的信息发送给目标方
<iq to="android@192.168.1.113/Spark 2.6.3" type="set" id="iq_19" from="iphone@192.168.1.113/xiff">
<query xmlns="http://jabber.org/protocol/bytestreams" mode="tcp" sid="82B0C697-C1DE-93F9-103E-481C8E7A3BD8">
<streamhost port="7777" host="192.168.1.113" jid="proxy.192.168.1.113" />
</query>
</iq>
然后就进入连接阶段,也就是初始方和目标方分别和代理建立socks5连接的过程。(关于SOCKS5协议连接,我之后会补充)。
目标方收到代理信息后和代理建立socket连接(使用SOCKS5协议连接),连接成功后通知初始方使用的代理jid
<iq id="iq_19" to="iphone@192.168.1.113/xiff" type="result" from="android@192.168.1.113/Spark 2.6.3">
<query xmlns="http://jabber.org/protocol/bytestreams">
<streamhost-used jid="proxy.192.168.1.113"/>
</query>
</iq>
初始方开始与代理建立socket连接(也使用SOCKS5协议),连接成功后给代理发送请求,要求激活文件流
<iq to="proxy.192.168.1.113" type="set" id="iq_21" from="iphone@192.168.1.113/xiff">
<query xmlns="http://jabber.org/protocol/bytestreams" sid="82B0C697-C1DE-93F9-103E-481C8E7A3BD8">
<activate>android@192.168.1.113/Spark 2.6.3</activate>
</query>
</iq>
代理回复激活成功信息
<iq type="result" id="iq_21" from="proxy.192.168.1.113" to="iphone@192.168.1.113/xiff"/>
初始方收到回复信息后就进入二进制流传输阶段,这时就可以开始发送二进制流了
等初始方将流发送完毕后把socket流关闭传输就完成了文件的传输。
注意:type为result的回复信息使用的id一定要和请求的信息id一样。
分享到:
相关推荐
【标题】:“openfire+smack开发webim笔记”涉及的知识点详解 【一】XMPP(可扩展消息处理现场协议) XMPP是一种基于XML的即时通讯协议,它最初源于Jabber项目,用于实现服务器之间的即时消息传递和在线状态探测。...
OpenFire是一款开源的即时消息服务器,它基于XMPP(可扩展通讯和表示协议)协议进行通信。OpenFire为国内企业提供了便利,尤其在移动互联网背景下,IM...本书不仅是作者的学习笔记,也是一本适合读者参考的实用指南。
通过深入研究和理解这个源代码,开发者可以学习到如何在Android上构建XMPP客户端,如何处理网络通信,以及如何与Openfire服务器集成。这将为创建自己的即时通讯应用奠定坚实基础。同时,了解源码结构和编程实践也有...
【Smack学习笔记】 Smack是一个流行的开源Java库,用于实现XMPP(可扩展消息处理和Presence协议),这是一种广泛用于即时通讯(IM)的应用层协议。通过使用Smack,开发者可以构建自己的XMPP客户端,实现用户之间的...
(整理)文献检索 土木工程项目成本管理.doc
(C++)利用keil编写51单片机收集温湿度的代码,并且利用QT实现一个简单的串口通信界面来接受单片机收集到的温湿度数据发送到PC端,其中下位机利用protues来实现.zip
实验二 数码管显示驱动设计
双动子龙门模组sw16可编辑_三维3D设计图纸_三维3D设计图纸.zip
内容概要:本文详细介绍了利用Norrbin/Fossen模型和反步法(PID)控制算法实现无人船(USV)路径跟踪的方法,特别是在存在洋流扰动的情况下。首先,文章解释了Norrbin模型用于描述船舶低频运动特性的优势,并展示了如何将洋流速度从惯性坐标系转换到船体坐标系。接着,讨论了LOS制导算法的改进,使其能够适应洋流影响。然后,阐述了反步法控制律的设计及其与PID控制的结合,强调了虚拟控制量的设计和参数调整的重要性。最后,通过Matlab/Simulink进行建模和仿真实验,验证了该方法的有效性,并提供了详细的代码实现和可视化结果。 适合人群:从事无人船控制系统研究和开发的技术人员,尤其是对路径跟踪和海洋环境扰动补偿感兴趣的工程师和研究人员。 使用场景及目标:适用于需要提高无人船在复杂海况下路径跟踪精度的应用场合,如海洋测绘、环境监测等。目标是通过引入先进的控制算法,减少洋流等外界因素对路径跟踪性能的影响,从而提高系统的鲁棒性和可靠性。 其他说明:文中提供的代码片段和仿真结果有助于读者理解和复现实验过程。同时,作者分享了许多实践经验,如参数调整技巧和常见错误避免,对于初学者非常有帮助。此外,文章还提出了未来的研究方向,如加入自适应观测器以进一步改善抗扰动性能。
elasticsearch-analysis-ik-8.17.4.zip
内容概要:本文详细介绍了煤矿开挖区三维渗流仿真及其应力场耦合计算的关键技术和实现方法。首先,利用Python的pyvista库进行地质数据处理和三维可视化,确保模型结构完整。接着,采用FEniCS进行有限元求解,基于达西定律计算渗流场,并引入变渗透率模型处理渗透系数的变化。应力场计算则基于修正的Mohr-Coulomb准则,重点处理渗流-应力耦合项。通过ParaView进行可视化,展示了渗流路径和应力分布情况。文中还讨论了实际工程应用中的优化技巧,如并行计算、HDF5分块存储等。 适合人群:从事矿山工程、岩土力学、渗流力学研究的专业人士和技术人员。 使用场景及目标:适用于煤矿开采过程中对渗流场和应力场的预测和分析,帮助识别潜在的安全隐患,如突水风险点。通过仿真结果指导现场施工,提高安全性和经济效益。 其他说明:文中提供了多个Python代码片段,涵盖从模型构建到后处理的各个环节,有助于读者理解和复现相关技术细节。强调了理论与实际相结合的重要性,指出数值模型虽不能绝对精确,但能提供重要的参考依据。
内容概要:本文详细介绍了如何利用COMSOL Multiphysics 6.1版本进行3258-3824Hz频段内的声波阵面调控。主要内容涵盖模型搭建、材料参数设置、扫频方法、耦合边界条件以及后处理技巧。文中强调了压力声学和固体力学模块之间的耦合重要性,并提供了具体的代码示例来指导用户完成各项任务。此外,还讨论了一些常见的陷阱及其解决方案,如网格划分、求解器选择等。 适合人群:从事声学工程、机械工程及相关领域的研究人员和技术人员,尤其是那些希望深入了解COMSOL软件在声波调控方面应用的人士。 使用场景及目标:适用于需要精确控制声波传播路径的研究项目,例如开发新型声学设备或改进现有产品的声学性能。通过掌握文中提到的技术手段,可以帮助用户更好地理解和预测不同条件下声波的行为特征。 其他说明:文中不仅提供了理论解释,还有大量实用的操作提示和代码片段,便于读者快速上手实践。同时,作者分享了许多个人经验和心得,有助于避免常见错误并提高工作效率。
2017学年第二学期期末考试《土木工程制图》大作业.pdf
基于51单片机protues仿真的自动水龙头系统设计(仿真图、源代码、AD原理图、流程图) 自动水龙头设计 1、当人或物体靠近时,水龙头自动防水,而人或物体离开时水龙头自动关闭 2、采用红外传感器 3、使用电磁阀控制开关 4、设定延时,如果人或物体长时间没有离开,自动关闭水龙头; 5、仿真图、源代码、AD原理图、流程图;
可调角度带式锯床sw23可编辑_三维3D设计图纸_三维3D设计图纸.zip
内容概要:本文详细介绍了ResNet神经网络模型的构建与实现。首先定义了一个通用的倒置瓶颈块(UniversalInvertedBottleneckBlock),它包括三个卷积层和批标准化层,并引入了残差连接机制。接着基于此构建了Bottleneck模块,进一步扩展了倒置瓶颈块的功能,同样包含了跳跃连接来缓解梯度消失问题。最后,ResNet类整合了多个Bottleneck模块形成完整的网络结构,通过_make_layer方法按需创建不同深度的网络层。文中还提供了resnet50函数用于快速实例化预定义配置下的ResNet模型,并展示了如何创建模型实例、准备输入数据以及进行前向传播计算。 适合人群:对深度学习有一定了解,特别是熟悉PyTorch框架的开发者或研究人员;希望深入理解ResNet架构及其组件的工作原理的学习者。 使用场景及目标:①理解ResNet中倒置瓶颈结构的设计思想及其实现细节;②掌握如何利用PyTorch搭建复杂神经网络模型;③学习如何通过调整网络层数和参数设置来自定义适合特定任务需求的ResNet模型。 阅读建议:本文代码量较大,建议读者先熟悉PyTorch的基础操作,然后逐步阅读每个类和函数的定义,注意理解各部分之间的关系。可以尝试修改代码中的参数或者添加新的功能来进行实践练习。同时,可以通过查阅官方文档或相关资料加深对某些概念的理解。
小学,初中,高中 沉浸式虚拟现实3DLED屏 VR未来智慧教室 建设方案书.docx
内容概要:本文介绍了一种将物理信息融入Transformer模型用于高速公路车辆轨迹预测的新方法——PIT-IDM模型。该模型结合了Transformer强大的数据捕捉能力和IDM驾驶模型的物理约束特性,在每个时间步进行交替更新,确保预测结果既符合数据规律又遵守物理常识。文中详细描述了模型架构、关键组件如IDM参数估计器和自注意力机制的具体实现,以及训练策略和损失函数设计。实验结果显示,相较于传统的纯数据驱动模型,PIT-IDM在cut-in场景下的预测精度提高了23%,并且能够有效避免非物理性的离谱预测。 适合人群:对深度学习、自动驾驶技术和车辆轨迹预测感兴趣的科研人员和技术开发者。 使用场景及目标:适用于高速公路车辆轨迹预测的研究和应用开发,旨在提高预测准确性,尤其是在复杂交通状况下的短期预测性能。 其他说明:文中还讨论了一些具体的工程实现细节,如计算开销优化、数据预处理方法以及应对极端情况的解决方案。此外,作者指出该方法可以扩展应用于其他时序预测任务,如电力负荷预测和股票市场预测等。
内容概要:本文详细对比了递归与迭代两种编程方法,解释了它们在不同应用场景下的优缺点。文中通过多个选择题解析了递归基、递归参数等概念,强调了递归基的重要性,指出它是递归函数停止调用自身的条件。同时,通过实例展示了如何使用递归和迭代实现阶乘、斐波那契数列、数组求和等功能,并讨论了递归与迭代在内存占用、执行效率等方面的差异。此外,文章还探讨了递归和迭代在搜索算法(如广度优先搜索、深度优先搜索)、排序算法(如快速排序、归并排序)中的应用,指出了递归在处理树形结构和分治问题时的优势,以及迭代在处理有明确循环次数的任务时的高效性。 适合人群:具备一定编程基础的学习者,尤其是对递归和迭代概念存在疑惑的程序员。 使用场景及目标:①理解递归和迭代的基本概念及其在实际编程中的应用;②掌握递归基的作用,避免无限递归;③学会根据问题特点选择合适的算法实现方式,优化程序性能。 其他说明:本文不仅提供了理论知识,还通过具体的代码示例加深理解,建议读者在学习过程中动手实践,尝试将递归算法转换为迭代算法,以更好地掌握两者之间的转换技巧。
java