JRTP实时音视频传输(2)-使用TCP通信的案例

环境搭建等参考:JRTP实时音视频传输(1)-必做的环境搭建与demo测试

1.创建自己的demo

先将example1拷贝为myclienttcp.cpp和myservertcp.cpp

cp example1.cpp myclienttcp.cpp

cp example1.cpp myservertcp.cpp

改写jrtplib/JRTPLIB/examples/CMakeLists.txt,添加myclienttcp和myservertcp编译

重新生成Makefile并编译

shell 复制代码
sudo cmake CMakeLists.txt
sudo make

可以看到成功编译了myclienttcp和myservertcp源文件

编译通过,这里就去实现demo就行

2.demo源码-客户端

cpp 复制代码
#include <iostream>
#include <arpa/inet.h>
#include "rtptcpaddress.h"
#include "rtpsession.h"
#include "rtpsessionparams.h"
#include "rtptcptransmitter.h"
#include "rtpipv4address.h"
#include "rtptimeutilities.h"
#include "rtppacket.h"
#include "rtpabortdescriptors.h"

using namespace jrtplib;

#define SERVER_IP    "127.0.0.1"
#define SERVER_PORT  58008

int main()
{
    RTPSession session;
    RTPAbortDescriptors m_descriptors;

    RTPSessionParams sessionparams;
    sessionparams.SetAcceptOwnPackets(true);
    sessionparams.SetOwnTimestampUnit(1.0/10.0);

    m_descriptors.Init();

    RTPTCPTransmissionParams transparams;
    transparams.SetCreatedAbortDescriptors(&m_descriptors);
    int status = session.Create(sessionparams,&transparams,RTPTransmitter::TCPProto);

    if (status < 0)
    {
        printf("my client session create failed\n");
        return -1;
    }

    //初始化socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in addrSrv;
    addrSrv.sin_addr.s_addr = inet_addr(SERVER_IP);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(SERVER_PORT);

    printf("my client prepare to connect\n");

    //连接服务器
    connect( sock, (sockaddr*)&addrSrv, sizeof(sockaddr));

    RTPTCPAddress addr(sock);

    status = session.AddDestination(addr);
    if (status < 0)
    {
        printf("my client session add destination failed\n");
        return -1;
    }

    session.SetDefaultPayloadType(96);
    session.SetDefaultMark(false);
    session.SetDefaultTimestampIncrement(160);

    for (int i = 0; i < 50 ; i++)
        {
            std::string str("123456");
            //发送数据
            session.SendPacket((void *)str.c_str(), str.length(),0,false,10);

            printf("my client send packet:%s, len:%d, idx:%d\n", str.c_str(), str.length(), i);
            RTPTime::Wait(RTPTime(10, 0));
        }

    RTPTime delay(0.020);
    session.BYEDestroy(delay,"Client End",9);
}

3.demo源码-服务端

cpp 复制代码
/*
   Here's a small IPv4 example: it asks for a portbase and a destination and 
   starts sending packets to that destination.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include "rtppacket.h"
#include "rtptcpaddress.h"
#include "rtptcptransmitter.h"
#include "rtpsession.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtplibraryversion.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>

using namespace jrtplib;

#define SERVER_PORT  58008

void checkerror(int rtperr)
{
	if (rtperr < 0)
	{
		std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
		exit(-1);
	}
}

int main(void)
{
    int   nListener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (nListener == -1)
	{
		return  -1;
	}
 
	sockaddr_in   serverAddr;
	memset(&serverAddr, 0, sizeof(sockaddr_in));
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_addr.s_addr = INADDR_ANY;
	serverAddr.sin_port = htons(SERVER_PORT);
	int  nRet = bind(nListener, (sockaddr*)&serverAddr, sizeof(serverAddr));
	if (nRet == -1)
	{
		return  -1;
	}
	if (listen(nListener, 1) == -1)
	{
		return  -1;
	}
 
	printf("my server is listen ready, wait for connect\n");

	sockaddr_in   clientAddr;
	int  nLen = sizeof(sockaddr_in);
	int   nServer = -1;
	while (true)
	{
		nServer = accept(nListener, (sockaddr*)&clientAddr, (socklen_t *)&nLen);
		if (nServer == -1)
		{
			continue;
		}
		else
		{
			break;
		}
	}
	printf("my server connect new client\n");

	int status = -1;
	int  nPackSize = 45678;
	RTPSessionParams   sessparams;
	RTPSession m_RTPTCPSession;

	sessparams.SetProbationType(RTPSources::NoProbation);
	sessparams.SetOwnTimestampUnit(90000.0 / 25.0);
	sessparams.SetMaximumPacketSize(nPackSize + 64);

	RTPTCPTransmitter    *pTransparams =  new RTPTCPTransmitter(NULL);
	status = pTransparams->Init(false);
	if (status < 0)
	{
		printf("my server trans param init failed, reason:%s\n", RTPGetErrorString(status).c_str());
        return -1;		
	}
	status = pTransparams->Create(65535, NULL);
	if (status < 0)
	{
        printf("my server trans param create failed, reason:%s\n", RTPGetErrorString(status).c_str());
        return -1;		
	}

	status = m_RTPTCPSession.Create(sessparams, pTransparams);
	if (status < 0)
	{
        printf("my server trans session create failed, reason:%s\n", RTPGetErrorString(status).c_str());
        return -1;		
	}
	status = m_RTPTCPSession.AddDestination(RTPTCPAddress(nServer));
	if (status < 0)
	{
        printf("my server trans session add failed, reason:%s\n", RTPGetErrorString(status).c_str());
        return -1;		
	}

	while (1)
	{	
		m_RTPTCPSession.BeginDataAccess();
		
		// check incoming packets
		if (m_RTPTCPSession.GotoFirstSourceWithData())
		{
			do
			{
				RTPPacket *pack;
				
				while ((pack = m_RTPTCPSession.GetNextPacket()) != NULL)
				{
					// You can examine the data here
					printf("myserver recv packet buf:%s, len:%d\n", pack->GetPayloadData(), pack->GetPayloadLength());
					
					// we don't longer need the packet, so
					// we'll delete it
					m_RTPTCPSession.DeletePacket(pack);
				}
			} while (m_RTPTCPSession.GotoNextSourceWithData());
		}
		
		m_RTPTCPSession.EndDataAccess();

#ifndef RTP_SUPPORT_THREAD
		status = m_RTPTCPSession.Poll();
		checkerror(status);
#endif // RTP_SUPPORT_THREAD
		
		RTPTime::Wait(RTPTime(1,0));
	}
	
	m_RTPTCPSession.BYEDestroy(RTPTime(10,0),0,0);

	return 0;
}

4.demo运行测试

分别运行client和server ,可以看到数据正常传输到server端

用netstat查看连接端口信息,也能看到该端口目前的状态,属于TCP连接,实验成功

对环境搭建不清楚的可以看这篇博客~
JRTP实时音视频传输(1)-必做的环境搭建与demo测试

5.源码下载

哈喽~我是Embedded-Xin,沪漂嵌入式开发工程师一枚,立志成为嵌入式全栈开发工程师,成为优秀博客创作者,共同学习进步。

以上代码全部放在我私人的github地址,其中有许多自己辛苦敲的例程源码,供大家参考、批评指正,有兴趣还可以直接提patch修改我的仓库~:

https://github.com/Xuzhangxin/study_linux_project.git

觉得不错的话可以点个收藏和star~

相关推荐
WangYaolove13142 分钟前
请解释Python中的装饰器是什么?如何使用它们?
linux·数据库·python
群联云防护小杜16 分钟前
服务器被挂马怎么办?——解决服务器被挂马的方法和步骤
运维·服务器·网络协议·tcp/ip·安全·ddos
?crying24 分钟前
蓝队基础4 -- 安全运营与监控
网络·安全·web安全
7yewh31 分钟前
嵌入式硬件实战提升篇(一)-泰山派RK3566制作多功能小手机
linux·arm开发·驱动开发·嵌入式硬件·物联网·智能手机·硬件架构
茶颜悦色vv37 分钟前
蓝队知识浅谈(中)
网络·web安全·网络安全
Xlbb.41 分钟前
安全见闻6-9
网络·安全·web安全·网络安全
YRr YRr1 小时前
ubuntu ros 解决建完图后 保存的地图非常小的问题
linux·运维·ubuntu
脸ル粉嘟嘟1 小时前
常用命令之Linux&Oracle&Hive&Python
linux·hive·oracle
Wils0nEdwards2 小时前
Leetcode 整数转罗马数字
linux·python·leetcode
写bug的小屁孩2 小时前
websocket初始化
服务器·开发语言·网络·c++·websocket·网络协议·qt creator