开发windows客户端接收RTP视频流,当h264视频达到1080P 60fps的时候,按包来调用recvfrom的函数压力比较大,存在丢包的问题,windows的完成端口的性能效果当然可以解决这个问题,而boost的asio在windows上是基于完成端口来开发的,所以采用boost的asio和环形缓冲区的方法,可以解决接收单路大数据量udp包中丢包的问题。

需要引入的头文件为:

  1. #include "CircledBuffer.h"
  2. #include <iostream>
  3. #include <boost/asio.hpp>
  4. #include <boost/bind.hpp>

其中CircledBuffer.h是自定义的缓冲区的类,之后会有介绍,boost的两个文件是asio必需的两个文件。

需要定义的全局变量为:

  1. using boost::asio::ip::udp;
  2. boost::asio::io_service service;
  3. boost::asio::ip::udp::socket sock(service);
  4. boost::asio::ip::udp::endpoint sender_ep;
  5. CircledBuffer readBuffer;
  6. PacketBuffer* packet;

其中io_service是用来标示启动的,后面会调用run。sock和endpoint类似于描述符和sockaddr_in的关系。CircledBuffer和PacketBuffer*,是自定义缓冲区。

主函数为:

  1. int main(int argc, char* argv[]) {
  2. boost::asio::ip::udp::endpoint ep( boost::asio::ip::address::from_string("192.168.1.206"),
  3. 9002);
  4. sock.open(ep.protocol());
  5. sock.set_option(boost::asio::ip::udp::socket::reuse_address(true));
  6. boost::asio::socket_base::receive_buffer_size recv_option(8*65534);
  7. sock.set_option(recv_option);
  8. sock.bind(ep);
  9. packet = readBuffer.GetLast();
  10. sock.async_receive_from(boost::asio::buffer(packet->data, packet->bufferSize), sender_ep, &on_read);
  11. service.run();
  12. }

初始化ep和sock,其中udp接收的数量比较大的话,需要设定receive_buffer_size,然后bind,设置接受buffer为packet。

介绍一下async_receive_from函数,它有三个参数,分别为接收的buffer,远端的ep,注意与本端的ep不同,远端的ep不用初始化设置,再就是buffer收满后的回调函数。

回调函数的内容是:

  1. void on_read(const boost::system::error_code & err, std::size_t
  2. read_bytes) {
  3. std::cout << "read: " << read_bytes << std::endl;
  4. readBuffer.MoveNext();
  5. packet= readBuffer.GetLast();
  6. sock.async_receive_from(boost::asio::buffer(packet->data, packet->bufferSize), sender_ep, &on_read);
  7. }

与main函数的接收部分一致,这里用了不断的自身回调,来实现while recvfrom的功能。

补充说一句,用申请好的CircledBuffer,便于后期的多线程或者异步strand的处理,而不阻塞接收。

缓冲区类的代码:

头文件:

  1. #ifndef CIRCLED_BUFFER_H
  2. #define CIRCLED_BUFFER_H
  3. #include <memory.h>
  4. #include <boost/atomic.hpp>
  5. #define CIRCLED_BUFFER_SIZE 300
  6. #define BUFFER_SIZE 2000
  7. struct PacketBuffer
  8. {
  9. PacketBuffer(){bufferSize=BUFFER_SIZE;dataSize=0;}
  10. unsigned int bufferSize;
  11. unsigned int dataSize;
  12. char data[BUFFER_SIZE];
  13. PacketBuffer& operator=(PacketBuffer& other)
  14. {
  15. memcpy(data,other.data,other.dataSize);
  16. dataSize = other.dataSize;
  17. bufferSize = other.bufferSize;
  18. return *this;
  19. }
  20. };
  21. class CircledBuffer
  22. {
  23. public:
  24. CircledBuffer(unsigned int bufSize=CIRCLED_BUFFER_SIZE);
  25. public:
  26. ~CircledBuffer(void);
  27. PacketBuffer* GetAt(unsigned int idx){return &packets[idx];}
  28. PacketBuffer* GetLast()
  29. {
  30. return GetAt(writeIndex.load(boost::memory_order_consume));
  31. };
  32. void MoveNext()
  33. {
  34. unsigned int idx = writeIndex.load(boost::memory_order_relaxed);
  35. writeIndex.store((idx+1)%bufferSize,boost::memory_order_release);
  36. };
  37. unsigned int GetLastIndex(){return writeIndex.load(boost::memory_order_consume);};
  38. unsigned int GetSize(){return bufferSize;};
  39. protected:
  40. boost::atomic<unsigned int> writeIndex;
  41. unsigned int bufferSize;
  42. PacketBuffer* packets;
  43. };
  44. #endif

缓冲区类的构造函数与析构函数

  1. #include "CircledBuffer.h"
  2. CircledBuffer::CircledBuffer(unsigned int bufSize)
  3. :bufferSize(bufSize),
  4. writeIndex(0)
  5. {
  6. packets = new PacketBuffer[bufSize];
  7. }
  8. CircledBuffer::~CircledBuffer(void)
  9. {
  10. delete []packets;
  11. }

源代码下载链接

boost的asio接收单路大数据量udp包的方法的更多相关文章

  1. 大数据量下MySQL插入方法的性能比较

    不管是日常业务数据处理中,还是数据库的导入导出,都可能遇到需要处理大量数据的插入.插入的方式和数据库引擎都会对插入速度造成影响,这篇文章旨在从理论和实践上对各种方法进行分析和比较,方便以后应用中插入方 ...

  2. (转)预估大数据量下UV的方法

    在实际应用中,我们经常碰到这种情况,即要统计某个对象或者事件独立出现的次数.对于较小的数据量,这很容易解决,我们可以首先在内存中对序列进行排序,然后扫描有序序列统计独立元素数目.其中排序时间复杂度为O ...

  3. tomcat优化---大数据量提交tomcat时,tomcat无法接收导致页面无反应

    关于tomcat的一个优化问题: 有时候保存大数据量的数据时.tomcat不优化的话,页面会没反应.tomcat后台并不报错,仅仅是提示以下内容: 警告: More than the maximum  ...

  4. 大数据量冲击下Windows网卡异常分析定位

    背景 mqtt的服务端ActiveMQ在windows上,多台PC机客户端不停地向MQ发送消息. 现象 观察MQ自己的日志data/activemq.log里显示,TCP链接皆异常断开.此时尝试从服务 ...

  5. 大数据量下,分页的解决办法,bubuko.com分享,快乐人生

    大数据量,比如10万以上的数据,数据库在5G以上,单表5G以上等.大数据分页时需要考虑的问题更多. 比如信息表,单表数据100W以上. 分页如果在1秒以上,在页面上的体验将是很糟糕的. 优化思路: 1 ...

  6. MySQL大数据量快速分页实现(转载)

    在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢?     般刚开始学SQL语句的时候,会这 ...

  7. 【转载】大数据量传输时配置WCF的注意事项

    WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定 ...

  8. mysql innobackupex xtrabackup 大数据量 备份 还原

    大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推荐xtrabackup,这个工具比mysqldump要快很多. 一.Xtrabackup介绍 1, ...

  9. mysql innobackupex xtrabackup 大数据量 备份 还原(转)

    原文:http://blog.51yip.com/mysql/1650.html 作者:海底苍鹰 大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推 ...

随机推荐

  1. mongodb 中 Aggregation 的管道和分片集合( Pipeline and Sharded Collections)

    mongodb 中的aggretion 中,如果管道中存在一个与之相匹配的shard key ,那么这个管道只运行在与之相匹配的shard 中,在以前(3.2),pipeline 被分流,最后又由pr ...

  2. Oracle基本概念

    1. 数据库和实例 什么是数据库,其实很简单,数据库就是存储数据的一种媒介.比如常用的文件就是一种,在Oracle10g中,数据的存储有好几种.第一种是文件形 式,也就是在你的磁盘中创建一批文件,然后 ...

  3. freemarker日志实现过程分析

    freemarker有自己的log类,这是一个抽象类,具体的日志打印委托给classpath里面合适的日志jar包来执行,寻找合适日志jar的查找顺序是:Apache Log4J, Apache Av ...

  4. 【转】Android PullToRefresh (ListView GridView 下拉刷新) 使用详解

    最近项目用到下拉刷新,上来加载更多,这里对PullToRefresh这控件进行了解和使用. 以下内容转载自:http://blog.csdn.net/lmj623565791/article/deta ...

  5. codevs 2800 送外卖 TSP问题

    2800 送外卖 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond         题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份 ...

  6. oracle创建存储过程中遇到的问题

    create or replace PROCEDURE CLEAR AS tname varchar(200);BEGIN tname:='''immediate trace name flush_c ...

  7. ThreadPool(线程池)

    WPF使用ThreadPool.QueueUserWorkItem线程池防界面假死 时间:2012-01-09 20:44来源:http://luacloud.com 作者:luacloud 点击:1 ...

  8. 51nod 1732 LCS变形

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1732 1732 51nod婚姻介绍所 题目来源: 原创 基准时间限制:1 ...

  9. Windows下载安装虚拟机和CentOS7

    1,想要在Windows系统中安装linux系统,首先需要安装一个虚拟机VMware VMware 12下载地址:https://my.vmware.com/cn/web/vmware/info/sl ...

  10. uva11489 - Integer Game(考思维,找规律)

    从S开始时只能是两种情况: 1.现在总和已经是3的倍数了,那么因为每人每次只能拿走一个数,要保持拿走之后依然是3的倍数,那么就只能拿3,6,9这类数,用num统计一下,看看num奇偶性就知道谁最后拿了 ...