webRTC中的coturn服务安装

2023-05-16

目录

1、先准备一台云主机

2、安装coturn的依赖

2.1 依赖软件准备

2.1 安装依赖组件

2.2 安装coturn的持久化保存用户信息库

3、安装coturn

4、 coturn配置

4.1 创建用户

4.2 配置说明

4.3 收集配置信息

4.3.1 收集 listening-device 和 listening-ip

4.3.2 查看云主机公网IP

4.3.3 收集realm信息

4.3.4 收集user信息

4.3.5 生成 tls 证书

4.4 配置

5、 启动 coturn 并验证

5.1 启动 coturn

5.2 验证

参考博文


1、先准备一台云主机

主要厂商上都有免费的云主机可以申请,也可以自己购买一个来进行测试

本文中所讲示例即在云上的主机配置如下:

配置项配置值
CPU2核
内存4G
存储80G
OSCentOS 7.6

2、安装coturn的依赖

2.1 依赖软件准备

coturn的依赖软件如下:

OpenSSL, SQLite, libevent2, PostgreSQL, MySQL (or MariaDB) and Hiredis
你可以从以下他们的网站直接下载:
 - http://www.openssl.org (required);
 - http://www.libevent.org (required);
 - http://www.sqlite.org (optional);
 - http://www.postgresql.org (optional);
 - http://www.mysql.org (or http://mariadb.org) (optional);
 - https://github.com/mongodb/mongo-c-driver (optional);
 - http://redis.io (optional).

2.1 安装依赖组件

$ yum install -y openssl-devel
$ yum install -y libevent libevent-devel
$ yum install -y gcc gcc-c++

重点说明

  1. 在安装 libevent2 之前必须先安装 OpenSSL,因 libevent2 安装时会检测 OpenSSL是否安装及版本,OpenSSL 版本太低会导致 libevent2 的安装不成功,进一步影响 TURN Server 的 TLS 功能;
  2. 旧版本的 libevent 版本有一定的缺陷,所以请安装 libevent2 ;

如无法安装libevent-devel可下载后安装,如下:

$ wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz
$ tar -zxvf libevent-2.1.12-stable.tar.gz
$ cd libevent-2.1.12-stable
$ ./configure
$ make & make install

2.2 安装coturn的持久化保存用户信息库

用于持久化保存用户信息的库支持如下几种:

  • sqlite
  • postgresql
  • mysql
  • hiredis

以上四种选择其一安装即可。

默认是持久化保存在sqlite中,安装如下:

$ yum install -y sqlite 
$ yum install -y libsqlite3-dev

重点说明

            SQLite 必须安装版本 3.x以上。

如安装libsqlite3-dev失败,使用如下命令:

$ yum list | grep sqlite3
dspam-sqlite3.x86_64                     3.10.2-12.el7                 epel     
libsqlite3x.x86_64                       20071018-20.el7               epel     
libsqlite3x-devel.x86_64                 20071018-20.el7               epel     
preludedb-sqlite3.x86_64                 5.2.0-1.el7                   epel     
python-sqlite3dbm.noarch                 0.1.4-6.el7                   epel     
rubygem-sqlite3.x86_64                   1.3.5-4.el7                   epel     
rubygem-sqlite3-doc.noarch               1.3.5-4.el7                   epel     
soci-sqlite3.x86_64                      4.0.0-4.el7                   epel     
soci-sqlite3-devel.x86_64                4.0.0-4.el7                   epel     
sqlite3-dbf.x86_64                       2011.01.24-3.el7              epel     
uwsgi-plugin-sqlite3.x86_64              2.0.18-8.el7                  epel     
zabbix40-dbfiles-sqlite3.noarch          4.0.37-1.el7                  epel     
zabbix40-proxy-sqlite3.x86_64            4.0.37-1.el7                  epel     
zabbix50-dbfiles-sqlite3.noarch          5.0.19-1.el7                  epel     
zabbix50-proxy-sqlite3.x86_64            5.0.19-1.el7                  epel

从以上列表中可见 libsqlite3x.x86_64 和 libsqlite3x-devel.x86_64 ,安装这两个包即可,命令如下:

$ yum install -y libsqlite3x.x86_64
$ yum install -y libsqlite3x-devel.x86_64

如果想保存到mysql中,上面的sqlite安装选项需改成mysql相关的依赖项。

注意:一定要在./configure前,把sqlite或mysq依赖项安装好,否则./configure时无法识别出sqlite或mysql,最后make成功的版本,会显示xxx is not supported。

其他库的安装视你的选择,安装方法如下:

$ sudo yum install postgresql-devel
$ sudo yum install postgresql-server

$ sudo yum install mysql-devel
$ sudo yum install mysql-server

$ sudo yum install hiredis
$ sudo yum install hiredis-devel

3、安装coturn

下载coturn源码并编译,从网址(https://github.com/coturn/coturn/wiki/Downloads)或(Index of /turnserver)中下载需要版本源码。

$ wget https://coturn.net/turnserver/v4.5.2/turnserver-4.5.1.3.tar.gz
$ tar -zxvf turnserver-4.5.1.3.tar.gz
$ cd turnserver-4.5.1.3
$ ./configure --prefix=/usr/local/turnserver
$ make & make install

默认情况下,coturn使用SQLite数据库进行用户和设置。当TurnServer第一次启动时,会自动创建(空)该数据库。

创建软链接

ln -s /usr/local/turnserver/bin/turnserver /usr/bin/turnserver
ln -s /usr/local/turnserver/bin/turnadmin /usr/bin/turnadmin

4、 coturn配置

4.1 创建用户

使用命令turnadmin创建一个用户/密码,并添加到SQLlite数据库中

$ mkdir /var/lib/turn
$ cp /usr/local/turnserver-4.5.1.3/sqlite/turndb /var/lib/turn/turndb
$ turnadmin -k -u neu -p 123456 -r yourRealm
0x9301762d41ad637475d4c41d33a0e3ed
0: : SQLite connection was closed.
0: : log file opened: /var/log/turn_17050_2022-02-23.log

创建用户neu,密码为123456,同时指定realm为yourRealm,大家可根据自己的需求来更改。

执行 turnadmin 后有一串编码 0x9301762d41ad637475d4c41d33a0e3ed这串编码将需添加到配置文件,配置结果见后面的配置信息。

查看刚刚新建的用户信息,命令及结果如下:

$ cd /usr/local/turnserver
$ ./bin/turnadmin -l
neu[yourRealm]
0: : SQLite connection was closed.
0: : log file opened: /var/log/turn_17053_2022-02-23.log

4.2 配置说明

配置项说明
listening-device安装coturn的服务器上网卡名称
listening-iplistening-device 网卡上的内网IP,中继服务器的监听IP地址,可以配置多个;
listening-portConturn 监听UDP/TCP端口,默认为3478
relay-device同listening-device信息
relay-ip同listening-ip信息,中继服务器的IP地址;
external-ip公网IP,外部IP,当中继服务器在NAT网络内部时指定,此处可以不添加
tls-listening-portcoturn监听TLS/DTLS端口,默认为5349
server-name服务器名称,用于OAuth认证,默认和realm相同;
realm域名
userdb用于保存用户信息
cert/pkey自签名证书,cert和pkey配置的自签名证书用Openssl命令生成
lt-cred-mech要有这个配置项,否则不支持webrtc

说明:将TCP/UDP和TLS/DTLS分别定义监听端口是符合RFC5766规范的,但是通过配置两者能使用同一端口,不推荐;

4.3 收集配置信息

4.3.1 收集 listening-device 和 listening-ip

使用命令 ip addr 来查看本机的网卡和IP信息,具体如下:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:1b:6c:a0 brd ff:ff:ff:ff:ff:ff
    inet 172.26.13.148/18 brd 172.26.63.255 scope global dynamic eth0
       valid_lft 315273457sec preferred_lft 315273457sec

从以上信息分析如下:

  1.  listening-device 值使用 eth0;
  2.  listening-ip 值使用 172.26.13.148;

4.3.2 查看云主机公网IP

每个厂商的云主机管理方法不一,此处不作详细示例。

本次测试用云主机的公网IP为 121.1.1.86(非真实IP,自己做时请使用自己的公网IP

4.3.3 收集realm信息

根据前面4.1节中 turnadmin 命令的参数,确定 realm 的值取 yourRealm。

4.3.4 收集user信息

根据前面4.1节中 turnadmin 命令的参数,确定 user 的值取 neu:123456;分号前面是用户名,后面是密码。

4.3.5 生成 tls 证书

1. 运行如下命令生成签名证书 

$ openssl req -x509 -newkey rsa:2048 -keyout /usr/local/turnserver/etc/turn_server_pkey.pem -out /usr/local/turnserver/etc/turn_server_cert.pem -days 99999 -nodes 

其中,部分参数的意义如下:

  • -days 有效天数
  • -node 不加密密匙

根据上面的命令指定的路径,我们可以知道将在 /usr/local/coturn/etc 目录下生成 turn_server_pkey.pemturn_server_cert.pem 这两个文件。

在我的环境里面openssl命令执行时,会要求录入如下信息:

Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Zhejiang
Locality Name (eg, city) [Default City]:shaoxing
Organization Name (eg, company) [Default Company Ltd]:.
Organizational Unit Name (eg, section) []:.
Common Name (eg, your name or your server's hostname) []:172.26.13.148
Email Address []:

上面信息中,绿色加粗信息是要录入的信息,关键是IP地址这块,测试时,特意做了内网IP和公网IP都测试了下,测试时,未发现问题。

2. 查看证书文件

命令如下:

$ ls -la /usr/local/coturn/etc/turn_*
-rw-r--r-- 1 root root 1326 Feb 21 14:39 /usr/local/turnserver/etc/turn_server_cert.pem
-rw-r--r-- 1 root root 1704 Feb 21 14:39 /usr/local/turnserver/etc/turn_server_pkey.pem

4.4 配置

生成配置文件方法有两种:

方法一:

$ cp /usr/local/turnserver/etc/turnserver.conf.default /usr/local/turnserver/etc/turnserver.conf

方法二:

$ vi /usr/local/turnserver/etc/turnserver.conf

然后将如下配置信息直接粘贴到“方法一”生成的配置文件后面,或者直接粘贴到“方法二”生成空文档中即可,具体配置信息如下:

listening-device=eth0
listening-ip=172.26.13.148
listening-port=3478
tls-listening-port=5349	
relay-device=eth0
relay-ip=172.26.13.148
min-port=49512	
max-port=65535
external-ip=121.1.1.86
fingerprint
lt-cred-mech
realm=yourRealm
userdb=/var/lib/turn/turndb
user=neu:0x9301762d41ad637475d4c41d33a0e3ed
user=neu:123456
stale-nonce
no-loopback-peers
no-multicast-peers
mobility
no-cli
cert=/usr/local/coturn/etc/turn_server_cert.pem
pkey=/usr/local/coturn/etc/turn_server_pkey.pem

保存 turnserver.conf 并退出。

5、 启动 coturn 并验证

5.1 启动 coturn

 启动命令如下:

$ cd /usr/local/turnserver
$ ./bin/turnserver -o -a -f -r yourRealm -c /usr/local/turnserver/etc/turnserver.conf

最后的-r yourRealm 意为指定realm,要与创建用户时指定的realm一致。可用lsof -i:3478校验下是否启动成功,如果看到类似下面的输出,说明3478监听正常。

5.2 验证

webrtc-samples官网还提供了一个检测ice穿透的在线工具:Trickle ICE

参考下图,把stun和turn地址设置好,然后点击最下面的“Gather candidates”(收集候选链路)

此图为借用文章《》中的图片,图片中的部分信息说明如下:

  1. 图片中 TURN username 值为 turn:121.1.1.86:3478;
  2. 图片中 TURN username 值是本文的 neu ;
  3. 图片中 TURN password 值是本文的 123456;

如果看到最后的reply那一行,address里的ip与turn服务器的公网ip相同,说明中继成功。

--------------------------------

参考博文

1. webrtc笔记(1): 基于coturn项目的stun/turn服务器搭建;

2. WebRTC-在阿里云基于coturn搭建STUN\TURN服务器;

3. Turnserver服务器搭建;

4. 官方 INSTALL 文档;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

webRTC中的coturn服务安装 的相关文章

  • iOS 和 Safari 11 WebRTC 不收集 STUN/TURN Trickle ICE 候选者

    在 iOS 11 iPhone 5s 和 iPhone 7 或桌面上使用 Safari 11 时 我的 Web 应用程序无法通过 CoTURN 服务器收集 WebRTC 中继 ICE 候选项 Web 应用程序 建立单向音频 WebRTC 对
  • 使用媒体流扩展 (MSE) 显示 getUserMedia Stream 实时视频

    我正在尝试使用 getUserMedia 显示从网络摄像头获取的 MediaStream 并使用任何可能播放的机制将其中继到远程对等点 作为实验 我没有直接使用 webRTC 因为我想控制原始数据 我遇到的问题是我的视频元素不显示任何内容
  • iOS Webrtc - 捕获本地视频流时崩溃

    我正在尝试使用 Google 存储库中的 webrtc 库 我按照这些步骤创建了一个单独的项目 其中包含类似于 APPRTC 的说明和代码 并且我能够让它工作 我能够在两台设备之间进行会议 但是当我尝试与旧项目集成时 Webrtc 崩溃了
  • iOS 11(Beta)中的webKit支持WebRTC吗?

    我有一个 URL 可以在 iOS11 测试版 上的 Safari 上正常工作 音频 视频也可以正常工作 但是 当我使用 WKWebView 加载此 URL 时 它会给我一个错误 不兼容的浏览器 当我在 WebKit 中检查浏览器版本时 它会
  • 如何使用 MediaRecorder 作为 MediaSource

    作为学习 WebRTC 的练习 我试图并排显示本地网络摄像头和网络摄像头的延迟播放 为了实现这一目标 我尝试将记录的 blob 传递到 BufferSource 并使用相应的 MediaSource 作为视频元素的源 the ondataa
  • 未捕获的 ReferenceError:进程未定义简单对等 Javascript

    我目前正在学习 WebRTC 并使用 simple peer 和 React 和 Socket io 的 npm 包 当我尝试致电用户时 就会显示此错误 stream readable js 529 Uncaught ReferenceEr
  • 我可以在 DTLS-SRTP 加密中指定自己的加密密钥吗

    在 Chrome 中的 webrtc Web 应用程序中 我曾经通过覆盖 SDP 中的加密信息来指定自己的加密密钥 我现在正在迁移我的 webrtc Web 应用程序以使用 DTLS SRTP 进行加密 启用 DTLS 后 有没有办法告诉
  • Node教程一对多无加载远程服务器Stream Spinner动不停

    我对在项目中使用所需的 Kurrento 很陌生 但是当我克隆 git hub 上为 Kurento 提供的教程并遵循 one2Many 调用的说明时 首先 adapter js 的软件包损坏了 因为我成功解决了它们 但之后出现了一个问题
  • 如何运行媒体流

    我创建了一个网络摄像头流 navigator getUserMedia video true function stream videoTag src window URL createObjectURL stream videoTag p
  • 如何在webRTC android中将视频流数据录制为mp4?

    请帮我 我在中使用了这个例子https github com pcab AndroidRTC https github com pchab AndroidRTC将视频和音频从 Android 设备流式传输到其他 Android 设备 在这个
  • 我需要 TURN 服务器吗?

    在什么情况下我应该使用 TURN 服务器 现在我有一个运行完美的 WebRTC 应用程序 该应用程序即将发布 我是否需要设置自己的 TURN 服务器 或者可能仅适用于主要应用程序 WebRTC 可以通过多种方式进行连接 并且当它在第一个选择
  • 检测 MediaStreamTrack 是否为黑色/空白

    我正在与peerjs 创建视频聊天 我使用以下功能切换相机 开 关 function toggleCamera localStream getVideoTracks 0 enabled localStream getVideoTracks
  • webrtc - 获取网络摄像头的宽高比

    我正在尝试学习如何开发 webRTC 应用程序 我想知道是否可以获得相机的宽高比 我不知道它是否有帮助 但我正在使用 webrtc io 但是 if更好 我可以停止使用它 From MDN https developer mozilla o
  • WebRTC:通道、轨道和流与 RTP SSRC 和 RTP 会话之间的关系

    来自 Mozilla 网站 https developer mozilla org en US docs Web API Media Streams API https developer mozilla org en US docs We
  • 使用 WebRTC 构建 iOS 本机应用程序

    我找了4天了 还是没找到 我构建了所有库并将其集成到我的自定义项目中 但我不知道应该采取哪些步骤才能使其正常工作 我在代码示例 解释中发现的唯一内容是 tech appear in 2015 05 25 Getting started wi
  • Android 上 WebRTC 的自定义视频源

    Overview 我想使用自定义视频源通过 WebRTC Android 实现来直播视频 如果我理解正确的话 现有的实现仅支持 Android 手机上的前置和后置摄像头 以下类与此场景相关 Camera1Enumerator java ht
  • Webrtc 重新协商,Firefox 到 Chrome,反之亦然,不更新流

    我已经成功建立对等连接 但我无法在 Chrome Firefox 上进行正确的重新协商 我已按照重新协商的步骤 将相机 视频更改为屏幕共享时 更新流 曲目 添加 删除 Changer 这击中了需要谈判 改变者 创建报价 更改者 设置本地描述
  • WebRTC - 消除/减少共享视频流的设备之间的延迟?

    我很抱歉没有发布任何代码 但我正在尝试了解更多有关延迟和webRTC 最好的方法是什么remove latency between two or more devices that are sharing a video stream 或者
  • 为什么WebRTC需要ICE协议才能运行?

    据我了解 ICE协议用于发现从最终用户设备到 外部 的节点 设备 我不明白为什么需要它 数据包路由不是由路由器和交换机等网络设备负责吗 他们应该找到从网关到最终用户设备的最短路径 实际上 路由器会记住他们之前发现的那些路由 此外 NAT 协
  • 录制视频和音频并上传到服务器

    我想为网站添加视频录制功能 我一直在搜索并尝试所有可能的可用解决方案 但还没有任何工作正常 我已经尝试过以下解决方案 WebRTC 我知道使用 WebRTC 我们可以从网络摄像头和麦克风获取流 我发现了很多关于相同内容的文章 但没有一篇解释

随机推荐

  • 网络爬虫有什么用?怎么爬?手把手教你爬网页(Python代码)

    导读 xff1a 本文主要分为两个部分 xff1a 一部分是网络爬虫的概述 xff0c 帮助大家详细了解网络爬虫 xff1b 另一部分是HTTP请求的Python实现 xff0c 帮助大家了解Python中实现HTTP请求的各种方式 xff
  • TSLint学习

    TSLint是typescript格式验证工具 安装 npm install tslint typescript span class hljs comment save dev span yarn span class hljs buil
  • C++从1~m数字中任取k个元素,求所有组合算法

    define MAXN 100 int a MAXN 定位数组 用于指示选取元素集合数组的位置 xff0c 选取元素集合数组0 起始 void comb int m int r int cur 指示定位数组中哪个成员正在移进 unsigne
  • 宏的本质以及宏(包括函数式宏) 没有返回值概念

    由什么问题而引申的 xff1a 字符串 XX ENM USB 中的XX是会变的 xff0c 想写一个宏定义来表示该字符串 首先 xff0c 想到用 define STR xff08 x xff09 x 34 ENM USB 形式 xff0c
  • windows环境下curl报错:Protocol "'http" not supported or disabled in libcurl

    原因 xff1a window命令行不支持单括号引用 解决方案 xff1a 将单括号删除 例如 xff1a curl http localhost 9200 pretty 在window命令行应改为 xff1a curl http loca
  • 关于Gson解析失败:Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $

    找了半天 xff0c 终于搞定了 xff0c 不得不说 xff0c 这是个坚强的bug 真的是个坚强的bug 一把辛酸了 xff0c xff0c 啥也不说了 xff0c 希望遇到一样坑的小伙伴 别放弃 xff0c 你们还有我 哈哈 解决办法
  • Python+pandas+每天股票涨了多少

    第一步 xff1a 得到某支股票历年来的交易数据 方法见 xff1a https blog csdn net zwy 0309 article details 108217342 在此 xff0c 我使用以下脚本得到股票 xff08 代码
  • 通过串口实时打印Android内核调试log信息

    一 前言 在调试 Android的Linux内核时 xff0c 我们往往会通过打开对应模块的调试Log来查看一些关键信息 通常我们可以使用一些简单的查看方法 xff0c 比如 xff1a 在pc端装有adb工具时 xff0c 使用adb s
  • Spring XML配置文件详解

    spring配置文件是用于指导Spring工厂进行Bean生产 依赖关系注入 xff08 装配 xff09 及Bean实例分发的 34 图纸 34 Spring框架的配置文件是基于xml的 xff0c Spring强大的功能依赖于类型繁多的
  • 两行命令解决ubuntu22.04安装网易云音乐后点击图标无反应的问题

    感谢知乎用户 64 拉布 xff1a https zhuanlan zhihu com p 518108518 1 终端中输入以下命令 xff1a span class token builtin class name cd span op
  • 数据库MVCC多版本并发控制原理

    MVCC实现原理 频繁的加锁会带来什么问题 xff1f 读数据的时候没办法修改 修改数据的时候没办法读取 xff0c 极大的降低了数据库性能 数据库是如何解决加锁后的性能问题的 xff1f MVCC 多版本控制实现读取数据不用加锁 xff0
  • 学习笔记-----ButterKnife

    ButterKnife是一个专注于Android系统的View注入框架 ButterKnife bind this 一切findViewById Fragment Adapter中同样适用 xff0c ButterKnife bind th
  • 【Linux】vim 中批量添加注释

    本期主题 xff1a vim 中批量添加注释博客主页 xff1a 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限 xff0c 出现错误希望大家不吝赐 此文主要介绍两种方法 xff1a 方法一 xff1a 块选择模式
  • Exported service does not require permission警告

    很久没写过应用了 xff0c 今天写一个Service时 xff0c 在manifest文件的 lt service gt 标签发现了这个警告 lt service android name 61 34 SendService 34 gt
  • Windows服务器高并发处理IOCP(完成端口)详细说明

    本系列里完成端口的代码在两年前就已经写好了 xff0c 但是由于许久没有写东西了 xff0c 不知该如何提笔 xff0c 所以这篇文档总是在酝酿之中 酝酿了两年之后 xff0c 终于决定开始动笔了 xff0c 但愿还不算晚 这篇文档我非常详
  • linux下如何测试端口通不通(四种方法)

    一般情况下使用 34 telnet ip port 34 判断端口通不通 接下来通过本文给大家分享四种方法测试端口通不通 xff0c 感兴趣的朋友一起学习吧 一般情况下使用 34 telnet ip port 34 判断端口通不通 xff0
  • 教你Vim编辑器,如何删除一行或者多行内容

    如何从Vim中删除行 xff1f 如何删除多行 xff1f 本文介绍在Vim编辑器中删除行的不同方法文内含长段代码可复制可往左滑 xff0c 希望对大家有帮助 xff01 安装Vim 在Ubuntu Debian中的安装方式 sudo ap
  • VBoxManage常用命令用法

    VBoxManage命令常用用法 系统环境 xff1a CentOS 7 3 x86 64 VirtualBox版本 xff1a 6 1 22 VirtualBox扩展版本 xff1a 6 1 22 增加一个新的扩展包 VBoxManage
  • Centos7安装Redis

    一 安装gcc依赖 由于 redis 是用 C 语言开发 xff0c 安装之前必先确认是否安装 gcc 环境 xff08 gcc v xff09 xff0c 如果没有安装 xff0c 执行以下命令进行安装 root 64 localhost
  • webRTC中的coturn服务安装

    目录 1 先准备一台云主机 2 安装coturn的依赖 2 1 依赖软件准备 2 1 安装依赖组件 2 2 安装coturn的持久化保存用户信息库 3 安装coturn 4 coturn配置 4 1 创建用户 4 2 配置说明 4 3 收集