即时通讯软件架构

http://nopainnogain.iteye.com/blog/832017

http://blog.csdn.net/realxie/article/details/7270119

http://zoomq.qiniudn.com/ZQScrapBook/ZqSKM/data/20100325150259/index.html


个人理解:TCP是天生的长连接协议,主要看其上的协议

TCP连接一旦建立连接,通信双方就可以相互发送信息,可以看做是长连接

虽然http也是基于TCP的,但是其在通讯结束之后,浏览器就主动断开连接,所以看起来是 request-response的形式



poll方式
poll方式,也称为轮循,是大家都比较熟悉的一种数据同步方式,客户端定期去ping查询服务器,确定是否有需要的数据。例如,软件更新模块,客户端软件需要定期去查询官方网站,判断当前是否有更新的版本,如果有就提醒用户进行升级。邮件客户端,需要定期查询邮件服务器,查询是否有新的邮件。RSS阅读器,也是需要不断的查询rss地址的状态,如果有更新,就将数据拿回来。

当服务器没有数据的时候,poll方式会浪费大量的带宽。 为了降低带宽,通常是采用减低poll的频率来实现的,这就导致了消息的长延迟,实时性不高。像gmail的POP3邮件检查间隔从10分钟到1小时不等。

push方式
poll的问题在于很多情况下,通信信道是单向的。为了解决poll的问题,可以将通信信道设计为双向的,这样就可以服务器采用push的方式主动向客户端进行数据同步了。双向通信信道设计,考虑到要穿透NAT和防火墙,很多实现采用长连接。例如各种IM的实现:MSN是TCP的长连接,QQ是UDP模仿的长连接,GTALK是HTTP模仿的长链接。

push方式,服务器主动向客户端推送数据。当前实现push方式有两种方法:
1. 客户端首先连接到服务器,并维持长连接
2. 服务器能够直接访问到客户端,不需要长连接
在国内NAT和firewall遍地都是的情况下,第2种方法不是很可行,但是对于一些企业应用,这种方法还是不错的,比如后面提到的pubsubhubbub。

但是push方式,通常需要长连接,对于服务器端其实也是一个不小的压力,虽然现在C10K问题得到了比较好的解决,但是对于一些大规模互联网应用来讲,用户数是数以亿计的,单单是维持TCP连接,就需要太多的服务器。因此,除了一些实时性要求比较高的应用,现在push方式使用的范围还不是很广,例如push方式在IM、服务器监控等领域都有应用。

下面选取这两天看的两个东东,来理解一下poll和Push。
XMPP
xmpp类似于email系统,将一个消息从一个JID送达到另一个JID。xmpp通常被用作im,那么它是如何实现实时消息传送的呢。我们接下来讨论的BOSH技术就是解决这个问题的。BOSH也就是Bidirectional-streams Over Synchronous HTTP,在HTTP上模拟长连接,gtalk就是用的这种方法。
BOSH技术能够同时减小网络带宽和减小客户端响应的时间。其方案是对客户端的请求连接管理器不给于返回直到数据已经就绪,当客户端收取连接管理器返回的数据会向连接管理器发送下一个请求,于是连接管理器总是保持着一个客户端的请求,当服务器端数据就绪的时候,可以将数据封装在请求的响应包中,“推送”给客户端。
如果双向连接长时间没有数据,连接管理器负责给客户端发送一个空包,空包触发客户端发送新的请求,连接管理器通过这种机制判断连接是否已经中断,由于BOSH不是轮询的机制,带宽消耗比标准的TCP连接大不了多少。


由于大多数的客户端不支持HTTP的Pipeling(单一的连接上承载并发的请求),于是,客户端必须从第二条HTTP连接发送消息。当第二条HTTP连接有新的请求发送的时候,连接管理器将第一条连接中的请求返回,即便此时第一条连接中的返回的是空数据包。这样做的原因是让客户端有需要的话可以发送新的请求过来。客户段同一时间最多只能保持两条HTTP连接,否则的话,客户端必须等待旧的请求处理完之后才能发送新的请求

在网络经常中断的环境下,BOSH退化成每个数据请求一个新HTTP连接。然而,在通常情况下,网络环境良好,客户端可以使用http/1.1,这个时候,一个Session包含两个TCP长连接,所有的请求都在这两个长连接上传输。基本上任何时候,客户端通过一条连接能够推送数据到服务器,与此同时,服务器端可以“推送”数据到客户端。值得注意的是,这两条长连接的角色在客户端每发送一次请求则角色转换一次。

尽管大多数时间可以随时推送数据到对端,但是,如果一方刚刚推送完数据,则需要等一个网络来回的时间才能推送下一个数据。




pubsubhubbub
pubsubhubbub是Google的工程师开发的一种协议,可以在ATOM和RSS更新的时候,订阅者能实时得到更新,实现一种基于RSS Feed的类似Twitter的实时效果。
PubSubHubbub 协议在供稿网址内容更新后,能接近即时的得到通知(通过webhook回调)。sub(订阅者)向要订阅的RSS中指定的hub进行注册,hub和pub(发布者)之间通过poll和push等方式同步数据,然后hub向已经注册的sub推送更新后的数据。
这样,就能够实时的得到RSS的更新,而且避免了sub不断轮循pub,节省了带宽。但是,这有一个缺点,就是hub向sub推送消息,就回到最初我们讨论的两种方法,现在pubsubhubbub中sub大都要求为公网可访问,但是对于一些企业应用,像google reader,这样做还是会节省很大带宽的。

PubSubHubbub 协议概述如下:
1. 一个供稿网址( “主题” )通过<link rel="hub" ...> 标签在其Atom或RSS的XML文件中声明其Hub server (枢纽服务器) 。这个 Hub(s) 可以由feed的发布者运行,也可以是一个任何人都可以使用得社区 Hub (community hub)。
2. 一个订阅者(对某个主题有兴趣的服务器) ,首先正常的抓取Atom网址。如果Atom档案声明它是 Hub ,订阅者就可以避免重复查看网址,而是在feed的 Hub 注册和订阅更新。
3. 订阅者通过主题的URL的声明的 Hub 订阅这个主题。
4. 当作者更新主题时,Hub 被告知发生了一个更新。
5. 之后 Hub 有效提取 feed 然后同时将新更改后的内容广播向所有订阅的用户。


不管UDP还是TCP,最终登陆成功之后,QQ都会有一个TCP连接来保持在线状态。这个TCP连接的远程端口一般是80,采用UDP方式登陆的时候,端口是8000。因此,假如你所在的网络开放了80端口(80端口是最常用端口。。就是通常访问Web的端口,禁掉它的话,你的网络对你来说价值已经不大了),但没有屏蔽腾讯的服务器IP,恭喜你,你是可以登陆成功QQ的。

二、聊天消息通信。

 

    采用UDP协议,通过服务器中转方式。因此,现在的IP侦探在你仅仅跟对方发送聊天消息的时候是无法获取到IP的。大家都知道,UDP 协议是不可靠协议,它只管发送,不管对方是否收到的,但它的传输很高效。但是,作为聊天软件,怎么可以采用这样的不可靠方式来传输消息呢?于是,腾讯采用了上层协议来保证可靠传输:如果客户端使用UDP协议发出消息后,服务器收到该包,需要使用UDP协议发回一个应答包。如此来保证消息可以无遗漏传输。之所以会发生在客户端明明看到“消息发送失败”但对方又收到了这个消息的情况,就是因为客户端发出的消息服务器已经收到并转发成功,但客户端由于网络原因没有收到服务器的应答包引起的。

 

三、文件/自定义表情传送。

 

    大家都知道,QQ可以传送文件,可以发送自定义表情。先说官方表情。官方表情实际发送的是命令字,而没有发送表情。客户端收到命令字后,会自动解释为对应的表情。因此,QQ2008正式版的客户端发出的新版表情,在2007beta4及以前的版本无法找到相对应的表情,就无法解释,看到的就会是空白信息,但查聊天记录就会有[表情]字样。

    自定义表情的传送是以文件传输方式进行的。

    下面说文件传输方式:A要向B发送一个文件,于是发出一个文件传送请求。服务器收到这个文件传送请求后,转发给B,同时或者在B应答后,将A的IP地址同时发送给B。B这个时候就得到了A的真实IP。这里的IP是你的本机IP。也就是说,如果A处在内网,B得到的地址就是一个内网地址。B得到了A的地址之后,就会尝试去连接A。如果B也处于内网,那么,显然A跟B之间的连接是无法建立的。这个时候,客户端就会请求服务器进行文件中转。因为服务器具有公网 IP,处在内网的A跟B都是可以连接到服务器的,于是,A跟B的文件传送就通过服务器中转的方式,顺利进行。(注:服务器文件中转使用443端口)

 

*   注:什么是内网、公网

    内网、公网是两种Internet的接入方式。

    内网接入方式:上网的计算机得到的IP地址是Inetnet上的保留地址,保留地址有如下3种形式:

   10.x.x.x

   172.16.x.x至172.31.x.x

   192.168.x.x

    内网的计算机以NAT(网络地址转换)协议,通过一个公共的网关访问Internet。

    内网的计算机可向Internet上的其他计算机发送连接请求,但Internet上其他的计算机无法向内网的计算机发送连接请求。

    公网接入方式:上网的计算机得到的IP地址是Inetnet上的非保留地址。公网的计算机和Internet上的其他计算机可随意互相访问。

 

    所以,如果一个局域网只开放80端口,QQ是可以登陆成功的,也可以进行聊天。但传送文件也是不可以的,除非你们都在同一个内网。如果局域网还同时开放443端口,那么,恭喜你,QQ的功能你都可以正常使用。

 

 

QQ是不是TCP和UDP一起用?如果用UDP,如何做到信息的可靠发送? 

答Q即可以使用TCP也可以使用UDP,但QQ默认是使用UDP协议,因为UDP协议消耗资源小,发送速度快,但当UDP协议不能正常转发的时候,就会采用TCP协议进行发送. 

而信息的可靠发送是通过各种验证机制来完成的,这一点你可以去GOOGLE之类的网站去搜索下. 

 

QQ用的是UDP打洞技术还是HTTP遂道? 

答:发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服务器,只不过不是常用的那些,那个服务器是TX自行开发的

 

因为用户一般都是在局域网内,地址都为私有IP,IM服务器是如何将信息转发到用户的? 

答:如果使用TCP就没什么好说了~由内网向外网连接,只要能够连接上进行握手了,消息就可以畅通无阻的进行发送了.如果使用UDP的话,就是使用的打洞技术了,只要通道打通了,发送消息基本和TCP没什么区别,要做的只是维护消息的完整性而已.

 

 

QQ是一个基于TCP/UDP协议的通讯软件,而MSN是基于TCP协议的通讯软件。

 

那么QQ是如何通讯的呢?在TCP/IP协议中,唯一标识一个应用进程的是socket,它通过网络层的IP地址和传输层的端口号来实现,对与同一个IP地址的内部网络,通过不同的端口号来标识不同的QQ进程;当你登陆QQ游戏服务器的时候,服务器会保留你的保留IP地址和端口号信息,并在你的好友的QQ进程中进行列表显示,然后两个进程就可以通信了。 

  通常,发送文件的计算机首先要通过消息服务器将其IP地址发送给接收计算机,当接收计算机同意接收的确认消息反馈到消息服务器后,消息服务器将据此设置好文件传输对话。随即,发送计算机与接收计算机就会在确定好的端口范围内,建立起TCP或UDP连接开始文件的检索与传输。 

  在默认状态下,QQ优先采用了UDP(User Data Protocol,用户数据报协议)协议传送数据,而对可靠性要求高的数据通讯系统往往使用TCP协议传输数据。与TCP协议不同,UDP协议并不提供数据传送的验证机制——在整个文件传输过程中如果出现数据报的丢失,协议本身并不能作出任何的检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。 

  UDP协议适用于无须应答、要求时效的软件使用,这样的设计正好与QQ追求的目标相符,所以QQ优先使用了此协议进行一切功能应用。但是,由于  UDP协议具有不可靠性,常会因种种原因导致消息或数据的发送失败(很多时候会发现发送文件给对方接收时,对方根本收不到要求接收文件的消息。或是发送聊天消息时,对方根本没有收到过消息)。显然,UDP协议由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。QQ在数据传输上更注重实际性能,为了获得更好的使用效果,往往可以牺牲一定的可靠性。因此,使用QQ来传输数据,在很多时候就成了一个“不错”的选择。 

  一般内网传输首选QQ,速度最快,QQ的文件传输是直接个人对个人,采用P2P的传输方式,具有不需中转的优势,而且服务器都在国内,传输性能要高于外国IM软件。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值