原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/84957708
《JRtplib开发笔记(一):JRtplib简介、JThread库编译》: https://blog.csdn.net/qq21497936/article/details/84785284
《JRtplib开发笔记(二):JRtplib库编译、示例演示》: https://blog.csdn.net/qq21497936/article/details/84785593
《JRtplib开发笔记(三):JRtplib库编程使用说明》: https://blog.csdn.net/qq21497936/article/details/84957120
《JRtplib开发笔记(四):JRtplib的VS开发环境搭建以及Demo》: https://blog.csdn.net/qq21497936/article/details/84957708
JRtplib开发笔记(四):JRtplib的VS开发环境搭建以及Demo
前话
前面介绍了JRtplib的使用,接下来介绍如何加入到工程项目中,并使用该工程项目写一个简单的使用Demo。
搭建JRtplib开发环境(VS2017,VC++)
因为没有带Fec,所以传输数据还是会有丢包的情况,这点需要提醒读者,但是如果是局域网有线网络,基本可以忽略丢包的问题,但是如果是使用无线网AP那么首先AP要支持组播,其次组播丢包那是很严重的,如果传图基本是很难收完整的。
下面介绍写了一个简单的rtp接受端和客户端,接受端只发送,客户端只接收。在使用jrtplib之前需要将其添加进工程,当前我们以VS作为IDE,写一个VC程序(使用C语言调用C++),其他IDE参考VS即可,调用外部库不外乎就是三点:
- 引用时需要的头文件
- 编译时需要的dll/lib/.a(此处需要dll与运行时需要的dll一样)
- 运行时需要的dll(此处与编译时需要的dll一样)
步骤一:新建JrtplibDemo工程
使用VS2017新建VC++空工程,移除创建的项目,然后再添加sender和recver两个项目:
为了调试方便,我们启用多个项目调试,即运行时可设置运行调试哪些项目,如下图:
运行时,如下图:
步骤二:项目引用Jrtplib头文件和库文件
将之前的modules模块文件夹引入到工程中,
引入头文件:
引入库文件
复制库文件(运行时也需要使用库,所以需要将库dll文件复制到exe输出目录下)
Demo演示
可以设置时间戳,包间间隔,负载类型等等,此Demo未附带
发送端源码
#include <stdio.h>
#include <stdlib.h>
// rtp库依赖socket,必须再rtp库引入之前添加,否则会出各种错误
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
// rtp库引入
#include "rtpsession.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#pragma comment(lib, "jrtplib.lib")
using namespace jrtplib;
int main(void)
{
RTPSession rtpSession;
R TPSessionParams rtpSessionParams;
RTPUDPv4TransmissionParams rtpUdpv4Transmissionparams;
char buf[1024] = { 0x00 };
char ip[16] = { 0x00 };
int port = 0;
int ret = 0;
// 容易忽略,因为自写代码中没有调用socket,rtp有调用但是没有初始化
WSADATA dat;
WSAStartup(MAKEWORD(2, 2), &dat);
printf("This is sender!!!\n");
printf("Input destination ip:");
scanf("%s", ip);
printf("Input destination port:");
scanf("%d", &port);
printf("Destination %s:%d\n", ip, port);
rtpSessionParams.SetOwnTimestampUnit(1.0 / 1);
rtpSessionParams.SetUsePollThread(true);
rtpSessionParams.SetAcceptOwnPackets(false);
ret = rtpSession.Create(rtpSessionParams, &rtpUdpv4Transmissionparams);
if (ret < 0)
{
printf("Failed to RtpSession::Create, ret=%d\n", ret);
}
RTPIPv4Address addr(ntohl(inet_addr(ip)), port);
rtpSession.AddDestination(addr);
while (true)
{
printf("Input message:");
scanf("%s", buf);
if (strcmp(buf, "exit") == 0)
{
break;
}
ret = rtpSession.SendPacket((void *)buf, strlen(buf), 0, false, 1);
if (ret < 0)
{
printf("Failed to RtpSession::SendPacket, ret=%d\n", ret);
continue;
}
else {
printf("Succeed to RtpSession::SendPacket!!!\n");
}
RTPTime::Wait(RTPTime(0, 100));
}
return 0;
}
接收端源码
#include <stdio.h>
#include <stdlib.h>
// rtp库依赖socket,必须再rtp库引入之前添加,否则会出各种错误
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
// rtp库引入
#include "rtpsession.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtppacket.h"
#pragma comment(lib, "jrtplib.lib")
using namespace jrtplib;
int main(void)
{
RTPSession rtpSession;
RTPSessionParams rtpSessionParams;
RTPUDPv4TransmissionParams rtpUdpv4Transmissionparams;
char ip[16] = "127.0.0.1";
int port = 0;
int ret = 0;
char buf[1024] = { 0x00 };
// 容易忽略,因为自写代码中没有调用socket,rtp有调用但是没有初始化
WSADATA dat;
WSAStartup(MAKEWORD(2, 2), &dat);
printf("This is recver!!!\n");
printf("Input local port:");
scanf("%d", &port);
printf("recv %s:%d\n", ip, port);
rtpSessionParams.SetOwnTimestampUnit(1.0 / 1);
rtpSessionParams.SetUsePollThread(true);
rtpSessionParams.SetAcceptOwnPackets(true);
rtpUdpv4Transmissionparams.SetPortbase(port);
ret = rtpSession.Create(rtpSessionParams, &rtpUdpv4Transmissionparams);
if (ret < 0)
{
printf("Failed to RtpSession::Create, ret=%d\n", ret);
}
RTPIPv4Address addr(ntohl(inet_addr(ip)), port);
#if 0
// 组播
rtpSession.JoinMulticastGroup(addr);
#else
// 本机接收,127.0.0.1
rtpSession.AddDestination(addr);
#endif
while (true)
{
rtpSession.BeginDataAccess();
if (rtpSession.GotoFirstSourceWithData())
{
do {
RTPPacket *packet;
while ((packet = rtpSession.GetNextPacket()) != NULL)
{
unsigned int recvSize = packet->GetPayloadLength();
unsigned char * recvData = (unsigned char *)packet->GetPayloadData();
memcpy(buf, recvData, recvSize);
buf[recvSize] = '\0';
printf("recv %d, message: %s\n", recvSize, buf);
rtpSession.DeletePacket(packet);
}
} while (rtpSession.GotoNextSourceWithData());
}
rtpSession.EndDataAccess();
RTPTime::Wait(RTPTime(0, 100));
}
return 0;
}
运行Demo效果
Demo下载地址
https://download.csdn.net/download/qq21497936/10843335
《JRtplib开发笔记(一):JRtplib简介、JThread库编译》: https://blog.csdn.net/qq21497936/article/details/84785284
《JRtplib开发笔记(二):JRtplib库编译、示例演示》: https://blog.csdn.net/qq21497936/article/details/84785593
《JRtplib开发笔记(三):JRtplib库编程使用说明》: https://blog.csdn.net/qq21497936/article/details/84957120
《JRtplib开发笔记(四):JRtplib的VS开发环境搭建以及Demo》: https://blog.csdn.net/qq21497936/article/details/84957708
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/84957708