热门标签 | 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流关闭传输就完成了文件的传输。


推荐阅读
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了如何使用iptables添加非对称的NAT规则段,以实现内网穿透和端口转发的功能。通过查阅相关文章,得出了解决方案,即当匹配的端口在映射端口的区间内时,可以成功进行端口转发。详细的操作步骤和命令示例也在文章中给出。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
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社区 版权所有