语音聊天应用程序(客户端/服务器)的结构?

时间:2010-01-19 22:00:45

标签: voip

我需要专家意见,对不起,如果我的问题本身就是一个混乱的问题。

我正在阅读有关VOIP应用程序(客户端/服务器)的结构。并且大多数建议将UDP用于语音流。我还检查了一些语音聊天应用程序,如paltalk和inspeak,他们的网站提到他们使用udp语音流,由于以下原因似乎不正确。

我检查了paltalk和inspeak使用的流量/端口。他们打开UDP和TCP端口并使用数据包嗅探器,我可以看到UDP通信不多,但主要是TCP通信正在进行。

据我所知,在UDP协议服务器无法向NAT后面的客户端(DSL路由器)发送数据。并且“UDP Braodcast”不是基于“互联网”的语音聊天应用程序的选项。这就是YAHOO在他们的文档中提到的,如果无法进行udp通信,yahoo messenger会切换到tcp。

所以我的问题是......

  1. 我在上述陈述中是否理解错误?

  2. 如果无法使用UDP,那么这些聊天应用程序会使用TCP Stream进行语音处理吗?

  3. 由于我经历过TCP语音流造成延迟,没有语音中断但语音延迟,那么语音聊天服务器/客户端通信的最佳结构应该是什么?

  4. 到目前为止,我认为,如果客户端将数据作为udp数据包发送到服务器和服务器通过TCP流将数据包分发给客户端,这是一个合适的解决方案吗?我的意思是这是商业语音聊天应用程序的作用吗?

    谢谢你的回答将帮助我和很多其他程序员。

    JF

2 个答案:

答案 0 :(得分:3)

UDP具有较少的开销(就总数据包大小而言),因此您可以将更多音频压缩到通道的带宽中。

UDP也是不可靠的 - 发送的数据包可能永远不会被接收或者可能无法接收 - 这对于语音应用来说实际上是可以的,因为你可以容忍一些信号质量的损失并继续前进。可以容忍少量丢失的数据包(而不是下载文件,每个字节都很重要)。

你可以使用TCP吗?当然,为什么不......它的开销略高,但这可能无关紧要。

SIP是支持UDP和TCP的语音/媒体标准。大多数部署都使用UDP,因为开销较低。

Skype协议在可能的情况下更喜欢UDP,然后回退到TCP。

在SIP情况下,NAT问题通过使用nat keep-alive数据包(任何请求/响应数据)来保持信道开启和打开,并利用大多数NAT将接受相同源上的回复的事实来解决端口连接是从...打开的...这不是万无一失的,并且通常需要一个代理服务器来调解2个nat'd对等体之间的连接,但它在许多部署中使用。

STUN,TURN和ICE是帮助NAT场景的其他方法,尤其是在p2p(无服务器)情况下。

关于NAT问题和媒体的信息:

http://www.voip-info.org/wiki/view/NAT+and+VOIP

http://en.wikipedia.org/wiki/UDP_hole_punching

http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html

如果您正在实施某种语音服务,FreeSwitch等系统提供了向分布式客户端提供媒体所需的大部分工具:

http://www.freeswitch.org/

答案 1 :(得分:1)

我看到这个问题已经过了3年了,但是我没有接受答案,所以我会对它进行拍摄

1-你的陈述是正确的

2-正确,TCP或UDP可用于音频流。

3-将音频流的tcp和udp组合起来没有用。如果UDP正在向服务器传输,它将用于接收,这就是所有NAT防火墙的工作方式,即它们在更改ip标头后将从内部主机接收的数据报发送到远程主机,以使数据包看起来像是来自它们,以及当他们收到回复时,他们会将其转发给内部主持人。 NAT防火墙之间的区别在于NAT隧道将保持活动多长时间,但这对于呼叫的音频部分无关紧要,因为在呼叫期间两种方式都有恒定的音频流。这对于使用SIP协议的呼叫的信令部分更重要。所以我建议使用TCP for SIP,因为TCP会话的默认超时时间为900秒,这使得保持活动消息的频率降低。

现在您提到的一些应用程序不使用SIP进行会话启动,因此具有专有的信令方式。

其他应用程序利用称为“打孔”的东西来允许客户端到客户端直接通信(或点对点),例如Skype。这些优点是服务器不会停留在语音流的中间,这可以有效地减少延迟,使TCP成为音频流的潜在选择。

着名的开源PBX Asterisk开发背后的人已经意识到SIP中需要打开大量端口的问题,他们已经开发了自己的协议,称为IAX,通过一个端口传输信令和媒体。我鼓励您考虑为您的客户端/服务器实施IAX,因为它确保如果客户端能够连接(通过信令),那么它就能够进行呼叫。