Qt调用jrtplib实现单播、多播和广播
来源:互联网 发布:用流量看淘宝费流量吗? 编辑:程序博客网 时间:2024/06/05 06:34
【来源】http://blog.csdn.net/caoshangpa/article/details/52571183
jrtplib简介可参考:http://blog.csdn.net/caoshangpa/article/details/51151942
RTP协议分析可参考:http://blog.csdn.net/caoshangpa/article/details/51149007
windows下编译jrtplib可参考:http://blog.csdn.net/caoshangpa/article/details/51152541
Linux下编译jrtplib可参考:http://blog.csdn.net/caoshangpa/article/details/51416822
linux下交叉编译jrtplib可参考:http://blog.csdn.net/caoshangpa/article/details/51416997
1.单播
单播是一种“一对一”模式,在单播通信方式下,当一端发送数据报到一个指定的主机时,首先可能会引发ARP把目的IP地址映射为MAC地址,然而ARP就是基于广播模式的实现。当以太网帧到达一个主机时,以太网接口便会把自己的MAC地址与帧中的MAC地址相比较,如果相符,以太网接口便会接收该帧,并按协议栈向上递交,如果不想符,该帧将会忽略该帧。其他的以太网接口做同样的操作,最后接收该帧的只有一个主机。在此之后,然后以太网帧向上递交到IP层目的主机会核对IP分组中的目的IP与本机IP(多宿主机),符合,根据协议类型向上递交到传输层相应的协议处理这即时单播通信的过程。典型的TCP通信就是单播模式的。
单播在网络中得到了广泛的应用,网络上绝大部分的数据都是以单播的形式传输的,只是一般网络用户不知道而已。例如,你在收发电子邮件、浏览网页时,必须与邮件服务器、Web服务器建立连接,此时使用的就是单播数据传输方式。但是通常使用“点对点通信”(Point to Point)代替“单播”,因为“单播”一般与“多播”和“广播”相对应使用。
- #include "crtpthread.h"
- #include <QDebug>
- CRtpThread::CRtpThread():
- m_runFlag(true)
- {
- #ifdef RECEIVER
- uint8_t destIP[]={192,168,1,168};
- #else
- uint8_t destIP[]={192,168,1,183};
- #endif
- initialRTP(destIP);
- }
- CRtpThread::~CRtpThread()
- {
- m_session.BYEDestroy(RTPTime(10,0),0,0);
- m_runFlag=false;
- #ifdef WIN32
- WSACleanup();
- #endif // WIN32
- }
- void CRtpThread::run()
- {
- while(m_runFlag)
- {
- usleep(1);
- m_session.BeginDataAccess();
- if (m_session.GotoFirstSourceWithData())
- {
- do
- {
- RTPPacket *pack;
- while ((pack = m_session.GetNextPacket()) != NULL)
- {
- int recvSize = pack->GetPayloadLength();
- uint8_t * recvData=pack->GetPayloadData();
- dispatch(recvData, recvSize);
- m_session.DeletePacket(pack);
- }
- } while (m_session.GotoNextSourceWithData());
- }
- m_session.EndDataAccess();
- #ifndef RTP_SUPPORT_THREAD
- int status = m_session.Poll();
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- #endif
- }
- }
- void CRtpThread::dispatch(uchar *dataBuf, int dataLen)
- {
- emit signalRtpData(dataBuf,dataLen);
- #ifdef RECEIVER
- //将收到的数据转发
- rtpSendData(dataBuf, dataLen);
- #endif
- }
- void::CRtpThread::initialRTP(uint8_t *ip)
- {
- #ifdef WIN32
- WSADATA dat;
- WSAStartup(MAKEWORD(2,2),&dat);
- #endif // WIN32
- //每秒发送10个样本
- m_sessionparams.SetOwnTimestampUnit(1.0/10.0);
- //设置本地端口
- m_transparams.SetPortbase(27000);
- int status = m_session.Create(m_sessionparams,&m_transparams);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- //设置目的IP和端口
- RTPIPv4Address addr(ip,27000);
- status = m_session.AddDestination(addr);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- //这里设置了默认值,发送的时候只用指定数据和长度SendPacket((void *)dataBuf,dataLen)。
- //否则发送时需指定后三个参数,例如SendPacket((void *)dataBuf,dataLen,0,false,10)。
- m_session.SetDefaultPayloadType(0);
- m_session.SetDefaultMark(false);
- m_session.SetDefaultTimestampIncrement(10.0);
- m_session.SetMaximumPacketSize(65535);
- }
- void CRtpThread::rtpSendData(uchar *dataBuf, int dataLen)
- {
- int status = m_session.SendPacket((void *)dataBuf,dataLen);
- if (status < 0)
- {
- qDebug() << RTPGetErrorString(status).c_str();
- }
- }
发送端和接收端分别如下图所示:
2.多播
多播是一种“一对一组”的模式,也就时加入同一个组的主机才会接收到数据,他综合了单播和广播的优点,可以只对特定的主机进行通信,其他的主机通信不受影响。多播通常被指IP多播,IP多播是一种通过使用一个多播地址将数据在同一时间以高效的方式发往处于TCP/IP网络上的多个接收者的协议。但是对于IP多播,扩容不容易。
“多播”也可以称为“组播”,在网络技术的应用并不是很多,网上视频会议、网上视频点播特别适合采用多播方式。因为如果采用单播方式,逐个节点传输,有多少个目标节点,就会有多少次传送过程,这种方式显然效率极低,是不可取的;如果采用不区分目标、全部发送的广播方式,虽然一次可以传送完数据,但是显然达不到区分特定数据接收对象的目的。采用多播方式,既可以实现一次传送所有目标节点的数据,也可以达到只对特定对象传送数据的目的。IP网络的多播一般通过多播IP地址来实现。多播IP地址就是D类IP地址,即224.0.0.0至239.255.255.255之间的IP地址。Windows 2000中的DHCP管理器支持多播IP地址的自动分配。
- #include "crtpthread.h"
- #include <QDebug>
- CRtpThread::CRtpThread():
- m_runFlag(true)
- {
- uint8_t destIP[]={224,212,118,99};
- initialRTP(destIP);
- }
- CRtpThread::~CRtpThread()
- {
- m_session.BYEDestroy(RTPTime(10,0),0,0);
- m_runFlag=false;
- #ifdef WIN32
- WSACleanup();
- #endif // WIN32
- }
- void CRtpThread::run()
- {
- while(m_runFlag)
- {
- usleep(1);
- m_session.BeginDataAccess();
- if (m_session.GotoFirstSourceWithData())
- {
- do
- {
- RTPPacket *pack;
- while ((pack = m_session.GetNextPacket()) != NULL)
- {
- int recvSize = pack->GetPayloadLength();
- uint8_t * recvData=pack->GetPayloadData();
- dispatch(recvData, recvSize);
- m_session.DeletePacket(pack);
- }
- } while (m_session.GotoNextSourceWithData());
- }
- m_session.EndDataAccess();
- #ifndef RTP_SUPPORT_THREAD
- int status = m_session.Poll();
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- #endif
- }
- }
- void CRtpThread::dispatch(uchar *dataBuf, int dataLen)
- {
- emit signalRtpData(dataBuf,dataLen);
- }
- void::CRtpThread::initialRTP(uint8_t *ip)
- {
- #ifdef WIN32
- WSADATA dat;
- WSAStartup(MAKEWORD(2,2),&dat);
- #endif // WIN32
- //每秒发送10个样本
- m_sessionparams.SetOwnTimestampUnit(1.0/10.0);
- //设置本地端口
- m_transparams.SetPortbase(27000);
- //设置网络接口IP地址
- // uint8_t interfaceIP[]={114,212,118,99};
- // m_transparams.SetMulticastInterfaceIP(*interfaceIP);
- //设置多播组数据的TTL值,范围为0~255之间的任何值
- m_transparams.SetMulticastTTL(255);
- int status = m_session.Create(m_sessionparams,&m_transparams);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- //是否支持多播
- bool iscast = m_session.SupportsMulticasting();
- if(!iscast)
- {
- m_session.Destroy();
- qDebug()<<"Do not support multicast";
- return;
- }
- //多播地址
- RTPIPv4Address addr(ip,27000);
- #ifdef RECEIVER
- //加入多播
- status = m_session.JoinMulticastGroup(addr);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- #else
- status = m_session.AddDestination(addr);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- #endif
- //这里设置了默认值,发送的时候只用指定数据和长度SendPacket((void *)dataBuf,dataLen)。
- //否则发送时需指定后三个参数,例如SendPacket((void *)dataBuf,dataLen,0,false,10)。
- m_session.SetDefaultPayloadType(0);
- m_session.SetDefaultMark(false);
- m_session.SetDefaultTimestampIncrement(10.0);
- m_session.SetMaximumPacketSize(65535);
- }
- void CRtpThread::rtpSendData(uchar *dataBuf, int dataLen)
- {
- int status = m_session.SendPacket((void *)dataBuf,dataLen);
- if (status < 0)
- {
- qDebug() << RTPGetErrorString(status).c_str();
- }
- }
发送端和接收端分别如下图所示:
3.广播
广播时一种“一对所有”模式,在广播模式下,该以太网帧被局域网中所有的以太网接口接收,并向上递交到传输层,如果指定的端口开启并绑定相应的应用进程时,应用进程就会处理该数据报,如果端口没有任何进程绑定,传输层就会丢弃该数据报。该主机并不会发送一个ICMP数据不可达的消息,否则会导致广播风暴。
广播风暴就是网络长时间被大量的广播数据包所占用,正常的点对点通信无法正常进行,外在表现为网络速度奇慢无比。出现广播风暴的原因有很多,一块有故障的网卡,就可能长时间向网络上发送广播包而导致广播风暴。“广播”在网络中的应用较多,如客户机通过DHCP自动获得IP地址的过程就是通过广播来实现的。
- #include "crtpthread.h"
- #include <QDebug>
- CRtpThread::CRtpThread():
- m_runFlag(true)
- {
- #ifdef RECEIVER
- uint8_t destIP[]={192,168,1,168};
- #else
- uint8_t destIP[]={192,168,1,255};
- #endif
- initialRTP(destIP);
- }
- CRtpThread::~CRtpThread()
- {
- m_session.BYEDestroy(RTPTime(10,0),0,0);
- m_runFlag=false;
- #ifdef WIN32
- WSACleanup();
- #endif // WIN32
- }
- void CRtpThread::run()
- {
- while(m_runFlag)
- {
- usleep(1);
- m_session.BeginDataAccess();
- if (m_session.GotoFirstSourceWithData())
- {
- do
- {
- RTPPacket *pack;
- while ((pack = m_session.GetNextPacket()) != NULL)
- {
- int recvSize = pack->GetPayloadLength();
- uint8_t * recvData=pack->GetPayloadData();
- dispatch(recvData, recvSize);
- m_session.DeletePacket(pack);
- }
- } while (m_session.GotoNextSourceWithData());
- }
- m_session.EndDataAccess();
- #ifndef RTP_SUPPORT_THREAD
- int status = m_session.Poll();
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- #endif
- }
- }
- void CRtpThread::dispatch(uchar *dataBuf, int dataLen)
- {
- emit signalRtpData(dataBuf,dataLen);
- }
- void::CRtpThread::initialRTP(uint8_t *ip)
- {
- #ifdef WIN32
- WSADATA dat;
- WSAStartup(MAKEWORD(2,2),&dat);
- #endif // WIN32
- //每秒发送10个样本
- m_sessionparams.SetOwnTimestampUnit(1.0/10.0);
- //设置本地端口
- m_transparams.SetPortbase(27000);
- int status = m_session.Create(m_sessionparams,&m_transparams);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- //设置目的IP和端口
- RTPIPv4Address addr(ip,27000);
- status = m_session.AddDestination(addr);
- if (status < 0)
- {
- qDebug()<< RTPGetErrorString(status).c_str();
- }
- //这里设置了默认值,发送的时候只用指定数据和长度SendPacket((void *)dataBuf,dataLen)。
- //否则发送时需指定后三个参数,例如SendPacket((void *)dataBuf,dataLen,0,false,10)。
- m_session.SetDefaultPayloadType(0);
- m_session.SetDefaultMark(false);
- m_session.SetDefaultTimestampIncrement(10.0);
- m_session.SetMaximumPacketSize(65535);
- }
- void CRtpThread::rtpSendData(uchar *dataBuf, int dataLen)
- {
- int status = m_session.SendPacket((void *)dataBuf,dataLen);
- if (status < 0)
- {
- qDebug() << RTPGetErrorString(status).c_str();
- }
- }
RTP协议一般用于单播和多播,如果开发中有广播的需求,广播与单播的唯一区别就是将发送端目标IP的最后字段设置为255,比如本例中的192.168.1.255,这样的话该网段的接收端都能收到发送端发送的数据。
发送端和接收端运行效果与多播相同。
使用jrtplib的一个具体例子: 基于RTP协议的H.264视频传输系统:实现
参考链接:http://blog.csdn.net/wye213/article/details/9896547
参考链接:http://blog.csdn.net/maopig/article/details/6863253
参考链接:https://docs.oracle.com/cd/E38902_01/html/E38880/sockets-137.html
源码链接:见http://blog.csdn.net/caoshangpa/article/details/52571183的评论
- 顶
- 5
- 踩
- 0
- 上一篇对软件架构设计的一些总结和理解
- 下一篇Qt通过UDP传图片,实现自定义分包和组包
- • 什么是单播、多播和广播、广播机制、组播
- • 单播,广播和多播
- • 转发:什么是单播、多播和广播
- • 通过live555实现H264 RTSP直播(Windows版)
- • linux 调用jrtplib 实现单播,多播,广播
- • 单播、多播(组播)和广播的区别
- • 单播、多播、广播
- • JAVA 单播、多播(组播)、广播
- • 关于计算机网络中的单播,多播,广播(粘贴)
- • 单播、多播与广播
- Qt调用jrtplib实现单播、多播和广播
- Qt调用jrtplib实现单播、多播和广播
- linux 调用jrtplib 实现单播,多播,广播
- 多播(组播)、单播、任播和广播
- 单播,广播和多播
- 单播、多播和广播
- 单播,多播和广播
- 单播、广播和多播地址
- 单播,广播和多播
- 单播、广播和多播
- 单播,广播和多播
- 单播、多播和广播
- 单播、多播和广播
- 单播,多播和广播
- 单播、广播、多播和IGMP
- 什么是单播、多播和广播
- 单播、多播和广播
- 单播、多播和广播
- hdoj 1257
- numpy里面的argmax函数
- SASS用法指南
- linux 进程调度
- C#对话框 文件路径
- Qt调用jrtplib实现单播、多播和广播
- 开发的应用程序启动不了
- javascript数字插入
- PL/SQL(五):存储过程
- Java基础——多态
- 简单添加host配置到jvm默认的dns查询缓存中
- 代理及动态代理
- ExtJs学习笔记(四)——动态修改store属性
- hdoj 1337