最近在研究XMPP协议,client端用的是开源的Gloox库,server使用gtalk server和OpenFire。昨天想实现XMPP的文件传输,于是仔细看了下XMPP的文件传输协议,结合协议和代码,算是把标准XMPP文件传输协议摸清楚了。下面是一些要点总结。
- XMPP主要支持两种形式的文件传输协议:SOCKS5 Bytestreams和 In-Band Bytestreams ,后者效率有问题,不建议使用。
- Sock5 Bytestreams支持点对点传输和通过Proxy中转。
- 标准XMPP,使用Disco来发现代理服务器,所以即使发送方没有配置proxy server也没有问题(理论上哈)。不错的机制啊。
- 点对点传输只支持Target去连接Requester,不支持双向,所以不是完全的P2P,Jingle file transfer对这一个应该做了优化。
- Gtalk由于采用了Jingle file transfer协议,所以没有提供用于文件传输的Proxy server,经过本人测试,下面提供解决方法:
1、发送文件的时候把自己启动一个sock5 server,以这个作为stream host。这种方式要求接受方必须是能够直连发送方,否则会出现失败。
2、指定第三方的Proxy server来实现文件传输,目前很多第三方proxy server貌似都会对ID做验证,所以最好是自己架设一个Sock5 Proxy server,实现起来应该不难。如果采用这中方式,建议不必要完全遵守XEP0065,可以对建立连接过程优化下,实现更彻底的“P2P”。(推荐)
3、使用In band bytestrreams方式。(不考虑性能的话,实现起来最简单)
4、在client端兼容Jingle协议。
1,2,3种方式只能实现第三方Client之间的文件传输,无法和官方Gtalk进行文件传输。
- 我用的是开源的gloox库,gloox库没有支持Proxy代理服务发现机制,所以发文件放必须至少添加一个Stremhost,一般来说发文件放把自己建立一个Sock5server,并把自己和代理服务器添加到Streamhost中,主要代码:
2
3 m_pSock5Server =new SOCKS5BytestreamServer( m_pClient->logInstance(), 6666 );
4 if( (m_pSock5Server->listen() ) != ConnNoError )
5 {
6 g_bLisened = TRUE;
7 }
8 m_pFt->registerSOCKS5BytestreamServer(m_pSock5Server);
9 m_pFt->addStreamHost(m_pClient->jid(), “127.0.0.1”, 6666 );
10 m_pFt->addStreamHost(JID(c_szProxyServer), c_szProxyServer, 7777);
相关协议:
XEP-0096: SI File Transfer
源文档 <http://xmpp.org/extensions/xep-0096.html>
XEP-0065: SOCKS5 Bytestreams
源文档 <http://xmpp.org/extensions/xep-0065.html>
XEP-0234: Jingle File Transfer(还没研究过,不过应该差不多)
关于作者