(转)用yate建立VoIP服务器 实现免费语音通话(SIP协议

原文链接:http://www.lxvoip.net/voip-beginner/yate-voip-server.html

 

介绍如何用yate2软件搭建VoIP服务器,并用SIP协议完成语音通话。在我的实例中,使用了局域网内的3台PC,Windows操作系统,接在同一个集线器上,并不是广域网或3G接入。

       网络电话是下一代网络(NGN)的重要应用之一。“下一代网络”是指10年以后的网络,全部基于软交换(Softswitch)技术。但是,拨打VoIP免费网络电话,并不需要在等待10年。基于现有的TCP/IP网络,我们已经可以使用开源的VoIP软件,实现PC-to-PC的免费语音通话。(注:这里的“免费”,是指不需要支付传统语音通话费用,ADSL/FTTB/3G等上网接入仍然是需要费用的)

下面,我将介绍如何用yate软件搭建VoIP服务器,并用SIP协议完成语音通话。在我的实例中,使用了局域网内的3台PC,Windows操作系统,接在同一个集线器上,并不是广域网或3G接入。


yate2建立VoIP服务器

Yate = Yet Another Telephony Engine,是一款开源的VoIP网络电话软件。它可以作为服务器、也可以作为客户端使用。yate2可以在Linux下运行、也可以在Windows下运行。yate2下载地址: www.lxvoip.net/softphone/yate.html 。


VoIP服务器可以干什么?

    * 客户端使用各自的用户名和密码登录到服务器上
    * 用户通过“电话号码”拨叫另一用户
    * 服务器负责转发拨叫请求及此后的其他控制信令
    * 服务器可以转发话音数据包

建立服务器这一步不是必须的。yate2支持两个客户端通过IP地址直接连接,而不需要建立服务器。如果你需要支持较多的用户能够互相通话,通常要建立服务器;如果只有2个用户,则可以采用直连方式。


建立VoIP服务器的前提条件

    * 一台计算机,作为服务器
    * 服务器通常需要拥有固定的公网IP地址
    * 服务器上不能再运行客户端(也就是说,客户端、服务器不能同时启动,否则会冲突)

用yate2搭建VoIP服务器的步骤

   1. 下载并安装yate2(最好完全安装所有组件,仅30MB)
   2. 打开yate2安装目录的conf.d子目录
   3. 将regfile.conf.sample复制一份,改名为regfile.conf,打开作下列修改:
          * 找到;auth=100、;register=100、;route=100三行,分别去掉前面的分号
          * 对需要建立的每一个用户,在文件末尾增加两行:
            [用户名]
            password=密码
            例如建立用户sunny,密码为870212,则写成:
            [sunny]
            password=870212
      这样,yate2服务器就有了身份认证功能
   4. 将regexroute.conf.sample复制一份,改名为regexroute.conf,打开作下列修改:
          * 找到[default],在后面增加一行
            ${username}^$=-;error=noauth
            这样未登录的用户就不能拨打电话
          * 对需要建立的每一个电话号码,在刚才插入处之后增加一行
            ^电话号码$=return;called=用户名
            例如当有人拨打号码15900941215,就呼叫用户sunny,则写成:
            ^15900941215$=return;called=sunny
      这样,yate2服务器就有了电话路由功能
   5. 开始-管理工具-服务,重新启动Yet Another Telephony Engine服务

如果服务成功启动、没有错误提示,你已经正确建立了最简单的yate2网络电话服务器。

http://www.lxvoip.net/voip-beginner/yate-voip-server.html
通过yate2服务器打电话


再次提醒,不能在运行yate2服务器的计算机上打开yate2客户端软件,否则是无法正常运行的。

   1. 开始-Yate-Yate Client,启动yate2客户端
   2. Accounts页-New,打开新建帐户对话框,填写各项目:
          * Protocol=sip
          * Use provider,不要选择
          * Account,可以随意输入
          * Username=用户名,@后面留空
          * Password=密码
          * Server=服务器的IP地址
      点击OK后,Status应该会显示“Registered”
   3. Calls页,Account=前面填写的account名称,然后输入另一个用户的电话号码,点击Call就可以打电话了
   4. 如果有电话打进来,选中它并点击Take the call就可以接听
   5. 点击Hangup挂断

yate2直连打电话

如果只有2个用户需要相互通话,就不必劳神建立VoIP服务器了(何况服务器还要占据一台计算机)。yate2支持直连通话,配置方法如下:

   1. 被叫用户只需开启Yate Client(当然要在防火墙中允许它),不需要配置
   2. 主叫用户,Accounts页-New,打开新建帐户对话框,填写各项目:
          * Protocol=sip
          * Use provider,不要选择
          * Account,可以随意输入
          * Username,留空
          * Password,留空
          * Server=被叫用户的IP地址
      点击OK后,Status并不会显示“Registered”,但是这没有关系
   3. 主叫用户,Calls页,Account=前面填写的account名称,然后随便输入一个号码,点击Call就可以打电话了
   4. 被叫用户,选中打进来的电话并点击Take the call就可以接听
   5. 点击Hangup挂断

SIP协议

yate2支持SIP、H.323、jabber、iax等多种VoIP协议,而先前我选择的是SIP协议。SIP协议定义了一组VoIP网络电话信令,传输层基于UDP协议、端口号为5060;SIP只提供控制信令,并不负责语音数据的编码和传输。
通过yate2服务器通话,SIP协议分析

我用Wireshark抓包分析了一次通话过程。这次通话的情况如下:(省略)


上面的过程,建立了主叫方-服务器、服务器-被叫方的两个VoIP电话连接;主叫方不知道被叫方的用户名和IP地址,被叫方知道主叫方的用户名、但不知道IP地址
现在出现大量的双向RTP数据包,封装了语音数据(甚至可以解码并窃听语音内容);使用随机高端口(在SIP协议的INVITE、200两种报文中,用SDP协议声明了RTP使用的UDP端口、语音编码方式等),经过服务器转发

登录(Register)与退出(Unregister)

假设有人拨打电话号码1。根据regexroute.conf,服务器知道号码1对应于用户lxvoip1。那么,服务器怎么知道u1的IP地址呢?这就需要通过接收登录与退出消息来记录用户状态。

    * 登录:
      REGISTER sip:192.168.1.50
      Contact:<sip:lxvoip1@192.168.1.183:5060>
      Expires:600
      To:<sip:lxvoip1@192.168.1.50>
    * 退出:
      REGISTER sip:192.168.1.50
      Contact:<sip:lxvoip1@192.168.1.183:5060>
      Expires:0
      To:<sip:lxvoip1@192.168.1.50>
    * 两者的区别就是Expires,0表示退出,非0表示登录
    * 如果缺少身份认证,服务器会返回401;通过身份认证后,服务器返回200

yate2直连通话,SIP协议分析


直接贴出Wireshark的自动分析结果吧~Statistics-VoIP Calls-Graph就可以看到

|Time     | 192.168.1.101     | 192.168.1.183     |
|3.985    |         INVITE SDP                    |SIP From: sip:anonymous@192.168.1.183 To:sip:0@192.168.1.183
|         |(5060)   ------------------>  (5060)   |
|4.004    |         100 Trying|                   |SIP Status
|         |(5060)   <------------------  (5060)   |
|4.035    |         180 Ringing                   |SIP Status
|         |(5060)   <------------------  (5060)   |
|11.818   |         200 OK SDP                    |SIP Status
|         |(5060)   <------------------  (5060)   |
|11.826   |         ACK       |                   |SIP Request
|         |(5060)   ------------------>  (5060)   |
|11.857   |         RTP (g711U)                   |RTP Num packets:281  Duration:5.597s SSRC:0x1726C94E
|         |(27392)  <------------------  (27824)  |
|11.954   |         RTP (g711U)                   |RTP Num packets:280  Duration:5.550s SSRC:0x7805579C
|         |(27392)  ------------------>  (27824)  |
|17.495   |         BYE       |                   |SIP Request
|         |(5060)   <------------------  (5060)   |
|17.514   |         100 Trying|                   |SIP Status
|         |(5060)   ------------------>  (5060)   |
|17.526   |         200 OK    |                   |SIP Status
|         |(5060)   ------------------>  (5060)   |



与经过服务器的通话相比,直连通话就显得非常简单了:没有身份认证过程,不需要转发信令与RTP数据。

posted @ 2012-08-27 16:30  loverszhaokai  阅读(2822)  评论(0编辑  收藏  举报