jrtplib如何收发数据?手把手教你实现基本功能!

吉云

最近捣鼓一个需要传实时数据的小玩意儿,想来想去,觉得用RTP协议比较合适,省得自己去造轮子处理丢包、时序这些麻烦事。网上搜了一圈,发现这个叫`jrtplib`的库评价还行,就决定拿它来试试水。

上手准备

第一步嘛肯定是把库弄下来。找到它的源码包,解压。看了下说明文档,它依赖另一个叫`JThread`的库,说是处理跨平台线程的,得,一起弄下来。先把`JThread`编译安装了,这个过程倒还顺利,没啥坑。

jrtplib如何收发数据?手把手教你实现基本功能!

接着编译`jrtplib`本身。我看文档和网上一些老哥的分享,提到一个编译选项,就是带不带线程支持。默认好像是不带的,接收数据得自己不停地调用一个叫`Poll`的函数去查。如果打开那个宏 `RTP_SUPPORT_THREAD` 再编译,库内部就会自己起个线程帮你收数据,用起来方便点。我寻思着后台收数据省事,就决定打开这个选项来编译。配置编译参数,加上这个宏定义,然后 `make`, `make install`,一套流程下来,库算是装好了。

开始写代码

库准备好了,就开始写点测试代码跑跑看。

先搞发送端:

  • 得先整个`RTPSession`对象出来,这玩意儿就代表一次RTP会话。
  • jrtplib如何收发数据?手把手教你实现基本功能!

  • 然后设置参数。主要是告诉它用哪个本地端口发数据,还有一些会话的基本信息。
  • 接着是最关键的,指定接收端的地址和端口。我先用本机测试,就填了`127.0.0.1`和随便一个没被占用的端口号。
  • 然后就可以循环发送数据了。我没真传视频流,就随便造了点字符串数据,打包成RTP包。这里要设置好负载类型(Payload Type)、时间戳这些东西。调那个`SendPacket`函数把数据发出去。

再搞接收端:

    jrtplib如何收发数据?手把手教你实现基本功能!

  • 接收端也一样,先创建一个`RTPSession`对象。
  • 设置本地监听的端口,这个端口必须跟发送端指定的目标端口一致。
  • 因为我编译时打开了线程支持,所以理论上不需要我自己循环调用`Poll`。库应该会在后台线程收到数据后,通过某种回调或者内部机制处理。但我初期测试为了保险,还是加了个循环,里面调用`Poll`看看有没有数据进来,或者检查特定状态。
  • 收到数据后,得从RTP包里把我的数据解出来。可以拿到发送端的地址信息,还有负载类型、时间戳、序列号等等。

实践中的小插曲

jrtplib如何收发数据?手把手教你实现基本功能!

刚开始跑的时候,发送端发出去了,接收端死活收不到。查了半天,防火墙也关了,地址端口也对了。后来仔细看代码,发现接收端创建`RTPSession`后,忘了添加接收地址了。虽然它监听了端口,但好像得明确告诉它允许从哪些源接收(或者说,至少得初始化接收相关的部分,即使是any source)。加上对源地址的配置或者检查初始化流程后,数据终于过来了。

还有就是那个线程支持。打开`RTP_SUPPORT_THREAD`后,确实不用自己疯狂`Poll`了。数据来了,库内部的线程会处理,然后可以通过库提供的一些接口或者回调(具体得看库的版本和用法)来获取数据。这让主逻辑清爽了不少。但要注意,用了库的内部线程,就得考虑多线程安全的问题了,比如访问共享数据时要加锁。

RTCP(RTP控制协议)也得留意。`jrtplib`会自动处理一些RTCP的包,比如发送报告(SR)和接收报告(RR)。这些包对网络状况统计、同步啥的挺重要。虽然我初期没太深入配置RTCP,但知道有这么个东西在后台跑,心里有数。

总的感觉

`jrtplib`用下来感觉还行。上手不算特别复杂,基本的RTP收发功能实现起来比较直接。文档虽然不是手把手教你,但结合例子和网上零散的资料,也能摸索着用起来。特别是那个线程支持选项,对于不想自己管理接收循环的场景来说,挺实用的。网络编程这东西,细节还是挺多的,用库也省不了完全理解协议和网络状况的功夫。这回实践下来,对RTP协议和`jrtplib`的使用算是有了个初步的了解,后面真要用到复杂的流媒体传输,估计还得再深入研究研究。

免责声明:由于无法甄别是否为投稿用户创作以及文章的准确性,本站尊重并保护知识产权,根据《信息网络传播权保护条例》,如我们转载的作品侵犯了您的权利,请您通知我们,请将本侵权页面网址发送邮件到qingge@88.com,深感抱歉,我们会做删除处理。

目录[+]