boost的asio接收单路大数据量udp包的方法
开发windows客户端接收RTP视频流,当h264视频达到1080P 60fps的时候,按包来调用recvfrom的函数压力比较大,存在丢包的问题,windows的完成端口的性能效果当然可以解决这个问题,而boost的asio在windows上是基于完成端口来开发的,所以采用boost的asio和环形缓冲区的方法,可以解决接收单路大数据量udp包中丢包的问题。
需要引入的头文件为:
- #include "CircledBuffer.h"
- #include <iostream>
- #include <boost/asio.hpp>
- #include <boost/bind.hpp>
其中CircledBuffer.h是自定义的缓冲区的类,之后会有介绍,boost的两个文件是asio必需的两个文件。
需要定义的全局变量为:
- using boost::asio::ip::udp;
- boost::asio::io_service service;
- boost::asio::ip::udp::socket sock(service);
- boost::asio::ip::udp::endpoint sender_ep;
- CircledBuffer readBuffer;
- PacketBuffer* packet;
其中io_service是用来标示启动的,后面会调用run。sock和endpoint类似于描述符和sockaddr_in的关系。CircledBuffer和PacketBuffer*,是自定义缓冲区。
主函数为:
- int main(int argc, char* argv[]) {
- boost::asio::ip::udp::endpoint ep( boost::asio::ip::address::from_string("192.168.1.206"),
- 9002);
- sock.open(ep.protocol());
- sock.set_option(boost::asio::ip::udp::socket::reuse_address(true));
- boost::asio::socket_base::receive_buffer_size recv_option(8*65534);
- sock.set_option(recv_option);
- sock.bind(ep);
- packet = readBuffer.GetLast();
- sock.async_receive_from(boost::asio::buffer(packet->data, packet->bufferSize), sender_ep, &on_read);
- service.run();
- }
初始化ep和sock,其中udp接收的数量比较大的话,需要设定receive_buffer_size,然后bind,设置接受buffer为packet。
介绍一下async_receive_from函数,它有三个参数,分别为接收的buffer,远端的ep,注意与本端的ep不同,远端的ep不用初始化设置,再就是buffer收满后的回调函数。
回调函数的内容是:
- void on_read(const boost::system::error_code & err, std::size_t
- read_bytes) {
- std::cout << "read: " << read_bytes << std::endl;
- readBuffer.MoveNext();
- packet= readBuffer.GetLast();
- sock.async_receive_from(boost::asio::buffer(packet->data, packet->bufferSize), sender_ep, &on_read);
- }
与main函数的接收部分一致,这里用了不断的自身回调,来实现while recvfrom的功能。
补充说一句,用申请好的CircledBuffer,便于后期的多线程或者异步strand的处理,而不阻塞接收。
缓冲区类的代码:
头文件:
- #ifndef CIRCLED_BUFFER_H
- #define CIRCLED_BUFFER_H
- #include <memory.h>
- #include <boost/atomic.hpp>
- #define CIRCLED_BUFFER_SIZE 300
- #define BUFFER_SIZE 2000
- struct PacketBuffer
- {
- PacketBuffer(){bufferSize=BUFFER_SIZE;dataSize=0;}
- unsigned int bufferSize;
- unsigned int dataSize;
- char data[BUFFER_SIZE];
- PacketBuffer& operator=(PacketBuffer& other)
- {
- memcpy(data,other.data,other.dataSize);
- dataSize = other.dataSize;
- bufferSize = other.bufferSize;
- return *this;
- }
- };
- class CircledBuffer
- {
- public:
- CircledBuffer(unsigned int bufSize=CIRCLED_BUFFER_SIZE);
- public:
- ~CircledBuffer(void);
- PacketBuffer* GetAt(unsigned int idx){return &packets[idx];}
- PacketBuffer* GetLast()
- {
- return GetAt(writeIndex.load(boost::memory_order_consume));
- };
- void MoveNext()
- {
- unsigned int idx = writeIndex.load(boost::memory_order_relaxed);
- writeIndex.store((idx+1)%bufferSize,boost::memory_order_release);
- };
- unsigned int GetLastIndex(){return writeIndex.load(boost::memory_order_consume);};
- unsigned int GetSize(){return bufferSize;};
- protected:
- boost::atomic<unsigned int> writeIndex;
- unsigned int bufferSize;
- PacketBuffer* packets;
- };
- #endif
缓冲区类的构造函数与析构函数
- #include "CircledBuffer.h"
- CircledBuffer::CircledBuffer(unsigned int bufSize)
- :bufferSize(bufSize),
- writeIndex(0)
- {
- packets = new PacketBuffer[bufSize];
- }
- CircledBuffer::~CircledBuffer(void)
- {
- delete []packets;
- }
boost的asio接收单路大数据量udp包的方法的更多相关文章
- 大数据量下MySQL插入方法的性能比较
不管是日常业务数据处理中,还是数据库的导入导出,都可能遇到需要处理大量数据的插入.插入的方式和数据库引擎都会对插入速度造成影响,这篇文章旨在从理论和实践上对各种方法进行分析和比较,方便以后应用中插入方 ...
- (转)预估大数据量下UV的方法
在实际应用中,我们经常碰到这种情况,即要统计某个对象或者事件独立出现的次数.对于较小的数据量,这很容易解决,我们可以首先在内存中对序列进行排序,然后扫描有序序列统计独立元素数目.其中排序时间复杂度为O ...
- tomcat优化---大数据量提交tomcat时,tomcat无法接收导致页面无反应
关于tomcat的一个优化问题: 有时候保存大数据量的数据时.tomcat不优化的话,页面会没反应.tomcat后台并不报错,仅仅是提示以下内容: 警告: More than the maximum ...
- 大数据量冲击下Windows网卡异常分析定位
背景 mqtt的服务端ActiveMQ在windows上,多台PC机客户端不停地向MQ发送消息. 现象 观察MQ自己的日志data/activemq.log里显示,TCP链接皆异常断开.此时尝试从服务 ...
- 大数据量下,分页的解决办法,bubuko.com分享,快乐人生
大数据量,比如10万以上的数据,数据库在5G以上,单表5G以上等.大数据分页时需要考虑的问题更多. 比如信息表,单表数据100W以上. 分页如果在1秒以上,在页面上的体验将是很糟糕的. 优化思路: 1 ...
- MySQL大数据量快速分页实现(转载)
在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢? 般刚开始学SQL语句的时候,会这 ...
- 【转载】大数据量传输时配置WCF的注意事项
WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定 ...
- mysql innobackupex xtrabackup 大数据量 备份 还原
大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推荐xtrabackup,这个工具比mysqldump要快很多. 一.Xtrabackup介绍 1, ...
- mysql innobackupex xtrabackup 大数据量 备份 还原(转)
原文:http://blog.51yip.com/mysql/1650.html 作者:海底苍鹰 大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推 ...
随机推荐
- Es6 export default 的用法
export 之后加上default意指默认接口的意思,在一个文件里面默认的只能有一个 其区别就是{} 在export中 引入需要用{}来盛放 //这是设置入口var a='my name is xi ...
- Windows10在待机状态时会卡屏的解决方案
问题:Windows10在待机时,会出现卡屏(鼠标.键盘都无法操作,只能重启电脑),区别于平时我们看得比较多的花屏.蓝屏.黑屏. 原因:经过一段时间的待机,Windows10会进入到降电节能模式,由于 ...
- HBase-协处理器详解及实现
协处理器(coprocessor) 把一部分计算移动到数据的存放端. 实例:HBase添加solr二级索引详细代码 简介 协处理器允许用户在region服务器上运行自己的代码,允许用户执行region ...
- SoapUI使用方法-01发送http请求
soap ui http://blog.csdn.net/russ44/article/details/51680083 一.发送HTTP请求消息 1.打开soapUI. 2.新建一个项目,实例如下: ...
- Java执行过程
Java的运行原理 在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能 ...
- Ceilometer Polling Performance Improvement
Ceilometer的数据采集agent会定期对nova/keystone/neutron/cinder等服务调用其API的获取信息,默认是20秒一次, # Polling interval for ...
- MySQL 基础知识(基本架构、存储引擎差异)
前言: // MySQL 并发.异步IO.进程劫持 最近在看高性能 MySQL,记录写学习笔记: 高性能 MySQL 学习笔记(一) 架构与历史 笔记核心内容:MySQL 服务器基础架构.各种存储引擎 ...
- LINUX CENTOS关机与重启命令详解
Linux centos重启命令: 1.reboot 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown -r 10 过10分钟自动重启(root用户使用) 4.s ...
- Hive group by实现-就是word 统计
准备数据 SELECT uid, SUM(COUNT) FROM logs GROUP BY uid; hive> SELECT * FROM logs; a 苹果 5 a 橙子 3 a 苹果 ...
- redhat linux 中设置网卡固定ip
更改 /etc/sysconfig/network-scripts/ifcfg-eth0(第一个网卡为eth0) DEVICE=eth0#网卡设备名称 ONBOOT=yes#启动时是否激活 yes | ...