用yate2实现软VoIP语音通话(SIP协议)

2024-02-12 12:32

本文主要是介绍用yate2实现软VoIP语音通话(SIP协议),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

用yate2实现软VoIP语音通话(SIP协议)

阳光男孩 发表于 2009-01-08

2009年1月7日,工业与信息化部发放了三张3G牌照,标志着中国进入了通信技术的新时代。3G的重要特性之一是高速数据链路,移动上网速度大大提高。同时,中国移动也大幅下调了2G网络GPRS上网的资费。可是,语音通话费用仍然按兵不动。作为永远处于弱势的用户,我们却可以通过VoIP网络电话自己实现免费语音通话。

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

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


yate2建立VoIP服务器

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


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

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


建立VoIP服务器的前提条件
一台计算机,作为服务器
服务器通常需要拥有固定的公网IP地址
服务器上不能再运行客户端(也就是说,客户端、服务器不能同时启动,否则会冲突)
用yate2搭建VoIP服务器的步骤
下载并安装yate2(最好完全安装所有组件,仅30MB)
打开yate2安装目录的conf.d子目录
将regfile.conf.sample复制一份,改名为regfile.conf,打开作下列修改: 
找到
;auth=100

;register=100

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

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


通过yate2服务器打电话

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


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

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


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

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


通过yate2服务器通话,SIP协议分析

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


服务器:192.168.1.50
主叫方:192.168.1.183,用户名u1,电话号码1
被叫方:192.168.1.101,用户名u2,电话号码2
通话过程:主叫方拨打号码2,被叫接听,稍后由主叫挂断

说明主叫方192.168.1.183 <=> 服务器192.168.1.50服务器192.168.1.50 <=> 被叫方192.168.1.101其他头部信息
发起呼叫=> INVITE sip:2@192.168.1.50 没有Authorization头,Call-ID:2126492930@192.168.1.50
 <= 100 Trying  
缺少认证<= 401 Unauthorized 包含WWW-Authenticate头
放弃呼叫=> ACK sip:2@192.168.1.50  
发起呼叫=> INVITE sip:2@192.168.1.50 From:<sip:u1@192.168.1.50>;tag=1542144666 ,包含Authorization头,Max-Forwards:20,Call-ID:2126492930@192.168.1.50
 <= 100 Trying  
转发呼叫 => INVITE sip:u2@192.168.1.50From:<sip:u1@192.168.1.50>;tag=831312670 ,没有Authorization头,Max-Forwards:19,Call-ID:495687575@192.168.1.50
  <= 100 Trying 
振铃 <= 180 Ringing 
转发振铃<= 180 Ringing  
接听 <= 200 OK 
确认 => ACK sip:u2@192.168.1.50From:<sip:u1@192.168.1.50>;tag=831312670
转发接听<= 200 OK  
确认=> ACK sip:2@192.168.1.50 From:<sip:u1@192.168.1.50>;tag=1542144666
上面的过程,建立了主叫方-服务器、服务器-被叫方的两个VoIP电话连接;主叫方不知道被叫方的用户名和IP地址,被叫方知道主叫方的用户名、但不知道IP地址
现在出现大量的双向RTP数据包,封装了语音数据(甚至可以解码并窃听语音内容);使用随机高端口(在SIP协议的INVITE、200两种报文中,用SDP协议声明了RTP使用的UDP端口、语音编码方式等),经过服务器转发
挂断=> BYE sip:2@192.168.1.50:5060 Reason:SIP;text="User hangup"
主叫方已经停止发送和接收RTP数据包,而被叫方的RTP包仍然不断经服务器转发到达,主叫方回应ICMP Port unreachable消息。
 <= 100 Trying  
 <= 401 Unauthorized  
挂断=> BYE sip:2@192.168.1.50:5060 这次带上Authorization头
 <= 100 Trying  
同意挂断<= 200 OK  
通知被叫挂断 => BYE sip:u2@192.168.1.101:5060 
服务器也停止接收RTP数据包,而被叫方的RTP包仍然不断到达,服务器回应ICMP Port unreachable消息。
  <= 100 Trying 
同意挂断 <= 200 OK 

登录(Register)与退出(Unregister)

 

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


登录:
REGISTER sip:192.168.1.50
Contact:<sip:u1@192.168.1.183:5060>
Expires:600
To:<sip:u1@192.168.1.50>
退出:
REGISTER sip:192.168.1.50
Contact:<sip:u1@192.168.1.183:5060>
Expires:0
To:<sip:u1@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数据

这篇关于用yate2实现软VoIP语音通话(SIP协议)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/702598

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现