文章首发及后续更新:https://mwhls.top/4116.html,无图/无目录/格式错误/更多相关请至首发页查看。
新的更新内容请到mwhls.top查看。
欢迎提出任何疑问及批评,非常感谢!
VoIP通话-基于SIP协议的Asterisk
这篇为 Demo,是我记录的初稿,该系列的后续文章都是从这里延伸的。
项目说明
项目内容
- 基于 Linux 编译并搭建 oSIP 系统并通过 IP 电话通信测试
项目介绍
- 在 Linux 中编译安装 oSIP 或 eXosip。
- 安装 mysql。
- 使用 IP 电话通信测试。
资料搜集
基本了解
- oSIP
- oSIP 在 GitHub 上开源了,并且给出了安装流程,但没有给出使用方式。
- eXosip
- eXosip 与 oSIP 一样在 GitHub 上开源了,是 oSIP 的扩展版本,同样只有安装,没有使用。
- IP 电话
- 搜索
oSIP IP电话
时,没有其他人的实现。
- 搜索
- 方向选择
- 现在已知了 oSIP 的安装方式,但不知如何与 IP 电话联系起来,但根据经验,可能是 oSIP 搭建通信链路与其它设备连接,IP 电话使用该链路与其它设备通信。
- 那么接下来应该先使用 IP 电话,看看缺了什么东西,或是哪些部分和 oSIP 相关。
IP 电话
- 软件选择
- 查阅资料了解到有的 IP 电话软件支持多客户端,考虑到需要 IP 电话通信,因此选择有 Windows、Linux、Android 客户端的软件。
- 下载安装 ZoiPer
- 官网:https://www.zoiper.com/
- 安装方式很朴素,略过。
- 启动 ZoiPer
- 启动,选择免费账户运行。
- 登录页面右侧说明可以用 VoIP 账号登录,猜测可能 oSIP 启动后会给出 VoIP 相关信息。
- 出于礼貌点击一下创建账号,发现要求选择服务提供商。
- 方向选择:
- ZoiPer 的登录使用的是 VoIP 账户,且创建账户时需要选择服务提供商,那么可推测 oSIP 运行后会给出 VoIP 信息。
- 因此接下来可查阅手册,或 oSIP 相关文章,看看是否会给出 VoIP 信息。
- 在 eXosip 里面搜到了 VoIP 的信息,网上较少 eXosip+VoIP 的文章,因此接下来先安装 eXosip。
Ubuntu 安装及配置
Ubuntu 安装
- 安装方式
- 本来是想用 docker 的,但是这 docker 真是绝啊,上一次是不能和宿主机通信,搞得我再本地又安了一次环境,这次直接启动不了了,可恶。
- 但我又不想按那两个虚拟机,用起来不是很顺手,所以选择了 Win11 的 WSL Linux:https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4—download-the-linux-kernel-update-package
- 下载地址:https://aka.ms/wslubuntu2004
- 安装
- 很朴素的安装方式,甚至不用选择,因此略过。
- 报错:参考的对象类型不支持尝试的操作。
- 卸载小黑盒加速器。
- 绝,真是绝,见:https://github.com/microsoft/WSL/issues/4194
- 进入与退出:
- 命令行输入
wsl
进入 ubuntu - 输入
exit
退出至 windows。 - 报错:
安装其中一个文件系统时出现错误。有关详细信息,请运行'dmesg'。
- 网上说
wsl --update
然后wsl --shutdown
即可,但我没成功。 - 我用 Tabby 里的 WSL 运行起来了,它似乎是运行了
C:\Windows\system32\wsl.exe
文件。
- 命令行输入
- 注意:
- 20.04的阿里源和清华源都用不了,好像是啥生命周期结束了?反正我没解决掉,上次我是用桌面版的换源,那玩意可好使了,但是这个没有,得先换源才能下载,可恶。
- 所以我又下了 22.04 的:https://www.microsoft.com/store/apps/9PN20MSR04DW
- 22的我用微软商店更快,而且更小,1G变500M,22k变9M,NB。
- *注意2**:可能是源的问题,我 22.04 也出问题,最后找到了个 163 源,正常,大家可以先试试再换版本。
Ubuntu 环境配置
- 换源:
- 参考:https://blog.csdn.net/xiangxianghehe/article/details/122856771
cd /etc/apt
sudo vim s
,按 a 进入输入模式,粘贴下载源,按 esc 进入模式选择,输入冒号,输入wq
保存退出。sudo cp sources.list sources.list.bak
,备份下载源sudo mv s sources.list
,覆盖下载源,一个个删不如覆盖来的快。- 163源:
deb http://mirrors.163.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ jammy-backports main restricted universe multiverse
- 更新:
sudo apt update
sudo apt upgrade
GCC 安装
- 安装原因:
- 查阅 eXosip 安装说明,发现推荐前置
c-ares
,而c-ares
需要 C 编译器,因此安装 GCC。 - 无 C 编译器报错:
configure: error: no acceptable C compiler found in $PATH
- 查阅 eXosip 安装说明,发现推荐前置
- 参考:https://blog.csdn.net/wjl18270365476/article/details/122659969
- 安装:
sudo apt install build-essential
c-ares 安装
- 下载:http://c-ares.haxx.se/
- 安装:
./configure
make
sudo make install
oSIP 与 eXosip 安装
- 参考:https://blog.csdn.net/mgledu/article/details/125100008
下载安装
- 下载:
- oSIP: http://ftp.gnu.org/gnu/osip/libosip2-3.6.0.tar.gz
- eXosip:http://download.savannah.nongnu.org/releases/eXosip/libeXosip2-3.6.0.tar.gz
- 解压:
tar -xf libeXosip2-3.6.0.tar.gz
tar -xf libosip2-3.6.0.tar.gz
- 安装 oSIP:
cd libosip2-3.6.0/
./configure
make -j8
sudo make install
- 安装 eXosip:
./configure
- `make’
sudo make install
查阅文档
文档:https://www.antisip.com/#exosip2-toolkit
VoIP 账号注册:
- 文档最后:Test with our sip service: sip.antisip.com
- 点进去发现有 VoIP,遂注册
- 登录 ZoiPer:
- 使用注册的 VoIP 账号登录 ZoiPer,所有协议均无效,但可进入界面。
发现文献:
- 发现一篇硕士学位论文,虽然有介绍代码,但看不懂。
- 基于oSIP协议栈的VoIP网关功能研究与实现
发现文章:
看到一篇 CSDN 的文章,提到用 Asterisk 搭建,想到或许可以曲线救国。
自己动手搭建免费VoIP服务器
安装 Asterisk
- 参考:自己动手搭建免费VoIP服务器
- 安装:
sudo apt install asterisk
- 备份配置文件:
sudo cp /etc/asterisk/sip.conf /etc/asterisk/sip.conf.backup
sudo cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.backup
配置 sip.conf
sudo vim /etc/asterisk/sip.conf
- 说明:这里和参考的那篇不同,因为我看到后面有重复设置,为了避免被后面设置项覆盖,我选择修改后增加内容,而非博主的直接增加。
- 修改
context=default
tcpenable = yes
- 添加
[general]
bindport = 5060
bindaddr = 0.0.0.0
tcpbindaddr = 0.0.0.0
[1001]
type = friend
username = 1001
secret=1001
host=dynamic
disallow = all
allow = ulaw
transport = udp
context=from-1001
[1002]
type = friend
username = 1002
secret = 1002
host = dynamic
disallow = all
allow = ulaw
transport = udp
context=from-1002
配置 extensions.conf
sudo vim /etc/asterisk/extensions.conf
- 说明:同样与参考的那篇不同,我发现已经有该参数了,所以省去。
- 添加
[from-1001]
exten => 1001,1,Answer()
exten => 1001,n,Dial(SIP/${EXTEN},20,tr)
exten => 1001,n,Hangup
[from-1002]
exten => 1002,1,Answer()
exten => 1002,n,Dial(SIP/${EXTEN},20,tr)
exten => 1002,n,Hangup
重启并检查
sudo /etc/init.d/asterisk restart
- 查看 Linux 端口:
sudo lsof -i:5060
- 有 asterisk 进程。
- 查看 Windows 端口:
netstat -aon| findstr 5060
,无进程tasklist | findstr asterisk
,无进程
- ZoiPer 无法连接:
- 发现 WSL 端口未映射至 Windows。
WSL 端口映射
- 安装
net-tools
sudo apt install net-tools
- 查看 WSL ip 地址:
ifconfig
- 即 eth0 的 inet,
172.31.220.163
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.31.220.163 netmask 255.255.240.0 broadcast 172.31.223.255
inet6 fe80::215:5dff:feb5:9751 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:b5:97:51 txqueuelen 1000 (Ethernet)
RX packets 23127 bytes 30204687 (30.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 15749 bytes 1157545 (1.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 端口映射
netsh interface portproxy add v4tov4 listenport=5060 listenaddress=0.0.0.0 connectport=5060 connectaddress=172.31.220.163
- 检查:
netsh interface portproxy show all
- 检查 5060 端口:
netstat -aon| findstr 5060
- 输出:
TCP 0.0.0.0:5060 0.0.0.0:0 LISTENING 5824
- ZoiPer 依然无法连接:
- 尝试 X-lite:https://x-lite.en.softonic.com/
其它 IP 电话软件测试
- 原因:ZoiPer 无法连接,不确定是什么原因,先试试其它软件。
X-lite
- 参考:安装、配置和测试Asterisk过程中遇到的问题及解决方法
- 下载:https://x-lite.en.softonic.com/
- 无法安装,疑似系统不兼容
转机
- 过了几天我再来试,我找到了 asterisk 官方教程:
- http://www.asterisk.org.cn/asterisk-cn-doc/doc/295240.html
- 发现他说的是 Asterisk 的 IP 地址,但我并不知道 Asterisk 的 IP,我知道 wsl 的 IP,即上面
ifconfig
的以太网 ip。 - 使用账号
1001
密码1001
,ip172.31.220.163:5060
,成功连接
测试 IP 通话
方向选择
- 如何通话?
- ZoiPer 有 Windows 版本和安卓版本,因此使用 Windows 客户端与安卓客户端通话
- 如何建立连接?
- 基于程序员的常识,我们需要在同一个局域网下才能互联。
- 当然,如果我有公网 IP,那我直接跟公网互连,我现在的 Asterisk 安装在本地的 WSL 中,本地没有公网 IP。
- 考虑到校园网是一个局域网,那么用校园网连接是一个选择。但我宿舍校园网 wifi 很烂,所以不考虑。
- 那么唯一的选择就是开放热点,服务器在电脑上,所以电脑开热点,手机连接。
开放热点及测试
- 吐槽:
- 开放热点怎么要我连接网络?而且我明明连了宽带,结果还是电脑连接校园网 wifi。
- ping
- 电脑 ping 手机-√:
- 查看热点连接的设备信息。我在电脑的设置-热点里看的
- ping 通。
- 电脑 ping WSL-√:
- ping 通。
- 这个其实没必要测,不过可以凑数
- WSL ping 电脑:
- 没 ping 通
- WSL ping 手机-√:
- ping 通,同电脑 ping 手机的 IP。
- 手机 ping WSL:
- 使用 WSL
ifconfig
的 IP,无法 ping 通。 - 使用电脑
ipconfig
中 WSL 的 IP,无法 ping 通 - 没 ping 通
- 手机 ping 电脑:
- 没 ping 通。
- 总结:
- 电脑能 ping 万物,但万物不能 ping 电脑,WSL 能 ping 手机。
安卓登录 ZoiPer
- 登录
- 使用电脑登录 ZoiPer 的 IP 连接,提示错误,且后面协议均
Not found
。 - 使用
ipconfig
的 WSL IP,同样Not found
。 - 使用
127.0.0.1
,同样Not found
。 - 使用本机地址,即电脑 ping 手机的 IP,能 ping 通,但
Not found
。
- 使用电脑登录 ZoiPer 的 IP 连接,提示错误,且后面协议均
- 可能错误原因
- 防火墙
关闭防火墙再次测试 ping
- WSL ping 电脑-√
- 很多 IP 都能 ping 通。
- 手机 ping 电脑-√
- wifi IP 可 ping 通。
- 手机 ping WSL
- 无法 ping 通
- 吐槽
- 手机可以 ping 热点中显示的 ip,电脑、WSL 也可以 ping 通这个 ip,那么防火墙的关闭确实有有效的。
- 并且手机 ping 该 ip 延时为 0.2ms,而电脑、WSL ping 延时为 70ms,那么该 ip 确实是手机的。
- 换思路
- 手机无法 ping 通 WSL,也就无法连上 Asterisk 服务器,需要改换思路。
- 改用 ZoiPer 的 PC 端与其它 ip 电话的 PC 端通话。
Linphone 与 ZoiPer 通话
下载与使用
- https://www.linphone.org/
- 使用 Asterisk 创建的两个账户,以及一个未创建的账户登录。
- 两个账户正常,未创建的账户报错,且识别到为 Asterisk 服务器,测试通过。
通话
- 测试通话,两个软件互相拨打,均
Not found
。
查阅资料
- 发现文章:VoIP语音通话研究【基础篇:环境搭建】
- 该文章也是用同一PC上的两个IP电话互相拨打,但用的是同一个软件。
- 博主提到使用
sip show peers
看用户,发现其 Host 不是 WSLifconfig
的,而是 Windowsipconfig
的,也许是 ip 的问题。 - 测试该 Host 的 ip 是否可行。
- 可行!
- NB!
- 此外,进入到上图的 asterisk 通信界面后能查看日志,上图是我用错误账号登录时的报错。
通话
- 下图为 ZoiPer 的1001账户向 Linphone 的1002账户拨打
- 下图为 Linphone 的1002账户向ZoiPer 的1001账户拨打
- 下图为两个软件的拨打历史
- 下图为两个软件的拨打时的截图,当我说话时,有声音
- 拨打六分钟后的通话记录
局域网内的通信失败
说明
- 由本机开放局域网,由其它安卓与电脑设备与本设备连接。
- 关闭双方防火墙后,局域网内电脑与手机间可相互 ping 通,WSL 可 ping 通局域网内设备,但 WSL 不可被局域网内其它设备 ping 通。
- 换句话说,架设于 WSL 的 Asterisk 服务器,可以与其它设备通信,但其它设备不能与服务器通信,这也导致了其它设备无法登陆 VoIP 账户,也就无法进行 IP 通话。
可能原因
- 我查了局域网设备无法连接 WSL 服务器的一些文章,他们通过端口映射让 WSL 端口映射至宿主机,这也是我前面有做的一点,但是这样只能让宿主机与 WSL 服务器通信,无法让局域网设备与 WSL 服务器通信。
- 猜测可能是 WSL 的一些限制,因为 WSL 实际上是与宿主机同时运行的,且共用一个存储系统,从这些地方可以认为 WSL 实际上是宿主机的软件。
- 然而,WSL 查询不到宿主机的进程,其占用的端口也不会在宿主机体现,那 WSL 也不会是一个宿主机的软件,不是属于一个将 linux 命令在 Windows 上处理的软件,更像是在 Windows 外的一条通路,Win 操作在 Win 路执行,Linux 操作在 WSL 路执行。
- 当然,考虑到这个报错:
安装其中一个文件系统时出现错误。有关详细信息,请运行'dmesg'。
贯穿我这台 WSL 的始终,我更愿意相信是我这个 WSL 的毛病,毕竟微软都已经单独设计出了一个端口映射,没必要还搞啥七七八八的让局域网连不了吧?
更多测试
- 有思路,还没做