JRtplib開發筆記(四):JRtplib的VS開發環境搭建以及Demo
原博主部落格地址: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庫程式設計使用說明
《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