热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

openfire文件传输xmpp

项目中需要用到openfire的文件传输,但是客户端使用flex,官方提供的xiff包中并没有封装文件传输的功能,没办法,研

项目中需要用到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&#61;"android&#64;192.168.1.113/Spark 2.6.3" type&#61;"set" id&#61;"iq_13" from&#61;"iphone&#64;192.168.1.113/xiff">
    
<si profile&#61;"http://jabber.org/protocol/si/profile/file-transfer" mime-type&#61;"text/plain" id&#61;"82B0C697-C1DE-93F9-103E-481C8E7A3BD8" xmlns&#61;"http://jabber.org/protocol/si">
        
<feature xmlns&#61;"http://jabber.org/protocol/feature-neg">
            
<xmlns&#61;"jabber:x:data" type&#61;"form">
                
<field var&#61;"stream-method" type&#61;"list-single">
                    
<option><value>http://jabber.org/protocol/bytestreamsvalue>option>
                    
<option><value>http://jabber.org/protocol/ibbvalue>option>
                
field>
            
x>
        
feature>
        
<file xmlns&#61;"http://jabber.org/protocol/si/profile/file-transfer" name&#61;"img0545.png" size&#61;"152443"><desc>senddesc>file>
    
si>
iq>

 
目标方接收到信息后发送回执&#xff0c;表示同意接收文件

 

<iq id&#61;"iq_13" to&#61;"iphone&#64;192.168.1.113/xiff" from&#61;"android&#64;192.168.1.113/Spark 2.6.3" type&#61;"result">
    
<si xmlns&#61;"http://jabber.org/protocol/si">
        
<feature xmlns&#61;"http://jabber.org/protocol/feature-neg">
            
<xmlns&#61;"jabber:x:data" type&#61;"submit">
                
<field var&#61;"stream-method">
                     
<value>http://jabber.org/protocol/bytestreamsvalue>
                     
<value>http://jabber.org/protocol/ibbvalue>
                
field>
             
x>
        
feature>
     
si>
iq>

 

这时进入XEP-0065协议阶段
初始方给服务器发送信息&#xff0c;请求提供代理服务器

 

<iq id&#61;"iq_15" type&#61;"get"><query xmlns&#61;"http://jabber.org/protocol/disco#items" />iq>


服务器回复信息&#xff0c;告知可用的代理

 

<iq type&#61;"result" id&#61;"iq_15" to&#61;"iphone&#64;192.168.1.113/xiff">
    
<query xmlns&#61;"http://jabber.org/protocol/disco#items">
        
<item jid&#61;"proxy.192.168.1.113" name&#61;"Socks 5 Bytestreams Proxy"/>
        
<item jid&#61;"pubsub.192.168.1.113" name&#61;"Publish-Subscribe service"/>
        
<item jid&#61;"conference.192.168.1.113" name&#61;"公共房间"/>
        
<item jid&#61;"search.192.168.1.113" name&#61;"User Search"/>
    
query>
iq>

 
这里选择name&#61;“Socks 5 Bytestreams Proxy”的代理&#xff0c;初始方给这个代理发送信息获取代理连接信息

 

<iq id&#61;"iq_17" to&#61;"proxy.192.168.1.113" type&#61;"get"><query xmlns&#61;"http://jabber.org/protocol/bytestreams" />iq>

代理方回复信息&#xff0c;告知初始方代理的jid、IP、端口等信息

 

<iq type&#61;"result" id&#61;"iq_17" from&#61;"proxy.192.168.1.113" to&#61;"iphone&#64;192.168.1.113/xiff">
    
<query xmlns&#61;"http://jabber.org/protocol/bytestreams">
        
<streamhost jid&#61;"proxy.192.168.1.113" host&#61;"192.168.1.113" port&#61;"7777"/>
    
query>
iq>

 
初始方收到代理信息后将代理的信息发送给目标方

 

<iq to&#61;"android&#64;192.168.1.113/Spark 2.6.3" type&#61;"set" id&#61;"iq_19" from&#61;"iphone&#64;192.168.1.113/xiff">
    
<query xmlns&#61;"http://jabber.org/protocol/bytestreams" mode&#61;"tcp" sid&#61;"82B0C697-C1DE-93F9-103E-481C8E7A3BD8">
        
<streamhost port&#61;"7777" host&#61;"192.168.1.113" jid&#61;"proxy.192.168.1.113" />
    
query>
iq>

 

然后就进入连接阶段&#xff0c;也就是初始方和目标方分别和代理建立socks5连接的过程。&#xff08;关于SOCKS5协议连接&#xff0c;我之后会补充&#xff09;。
目标方收到代理信息后和代理建立socket连接(使用SOCKS5协议连接)&#xff0c;连接成功后通知初始方使用的代理jid

 

<iq id&#61;"iq_19" to&#61;"iphone&#64;192.168.1.113/xiff" type&#61;"result" from&#61;"android&#64;192.168.1.113/Spark 2.6.3">
    
<query xmlns&#61;"http://jabber.org/protocol/bytestreams">
        
<streamhost-used jid&#61;"proxy.192.168.1.113"/>
    
query>
iq>

 
初始方开始与代理建立socket连接(也使用SOCKS5协议)&#xff0c;连接成功后给代理发送请求&#xff0c;要求激活文件流

 

<iq to&#61;"proxy.192.168.1.113" type&#61;"set" id&#61;"iq_21" from&#61;"iphone&#64;192.168.1.113/xiff">
<query xmlns&#61;"http://jabber.org/protocol/bytestreams" sid&#61;"82B0C697-C1DE-93F9-103E-481C8E7A3BD8">
<activate>android&#64;192.168.1.113/Spark 2.6.3activate>
query>
iq>

 
代理回复激活成功信息

 

<iq type&#61;"result" id&#61;"iq_21" from&#61;"proxy.192.168.1.113" to&#61;"iphone&#64;192.168.1.113/xiff"/>

初始方收到回复信息后就进入二进制流传输阶段&#xff0c;这时就可以开始发送二进制流了

等初始方将流发送完毕后把socket流关闭传输就完成了文件的传输。


推荐阅读
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • javax.mail.search.BodyTerm.matchPart()方法的使用及代码示例 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 本文详细介绍了在CentOS 6.5 64位系统上使用阿里云ECS服务器搭建LAMP环境的具体步骤。首先,通过PuTTY工具实现远程连接至服务器。接着,检查当前系统的磁盘空间使用情况,确保有足够的空间进行后续操作,可使用 `df` 命令进行查看。此外,文章还涵盖了安装和配置Apache、MySQL和PHP的相关步骤,以及常见问题的解决方法,帮助用户顺利完成LAMP环境的搭建。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • Flowable 流程图路径与节点展示:已执行节点高亮红色标记,增强可视化效果
    在Flowable流程图中,通常仅显示当前节点,而路径则需自行获取。特别是在多次驳回的情况下,节点可能会出现混乱。本文重点探讨了如何准确地展示流程图效果,包括已结束的流程和正在执行的流程。具体实现方法包括生成带有高亮红色标记的图片,以增强可视化效果,确保用户能够清晰地了解每个节点的状态。 ... [详细]
  • 最新消息显示,苹果即将发布的新一代iOS系统可能将集成先进的3D地图功能。这一创新技术由C3 Technologies公司开发,曾在今年3月被TechCrunch报道。用户可以通过该功能获得更加真实和沉浸式的地图体验,包括详细的建筑物模型和街景视图。视频演示展示了其卓越的视觉效果和交互性。 ... [详细]
author-avatar
丿艹约锭So灬幸福老师
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有