boost asio处理tcp和udp的不同之处及要点
来源:互联网 发布:淘宝一年销售额是多少 编辑:程序博客网 时间:2024/06/07 06:16
最近在看asio,打算基于asio重构媒体服务器中网络模块,学习的过程注意到了在udp和tcp中,对asio使用的所应该注意的地方,现记录下来
- tcp与udp的不同之处
老生常谈的tcp与udp最大的不同是,tcp是可靠的并且保证数据到达。udp是不可靠的,通俗的描述就是它只管发,至于对方是否收到数据,一概不负责。所以在处理tcp和udp上的读写操作就有很大不同,并且在读写缓存的管理上也有很大不同。
- 读写操作的不同之处
对tcp而言,比如发送100字节的数据,可能分成第一次发送10字节,第二次发送90字节。也可能第一次就将100字节全部发送完毕。也可能分成了三次发送完毕,第一次发送10字节,第二次发送30字节,第三次发送60字节。其发送的次序完全取决于当时的网络状况和当前tcp发送缓存及滑动窗口大小所决定。所以对接收方而言,当调用read返回时,其结果可能是只是接收到了一部分数据。要接收到完整的数据包,可能需要多次read操作。正是这种原因,应用层在处理tcp数据的收发时,通常需要通过某种方式先告知接收端当前数据包大小。比较常规的做法是在数据包的头几个字节定以数据包长度。
对于udp而言,数据收发的处理就简单很多,发送端只需要调用sendto,udp就会将整个数据包发送出去,对于超过mtu长度数据包,数据包将会截断至mtu长度。对接收端而言,调用revcfrom如果返回成功,意味着收到的是一个完整的数据包。所以对udp来说,唯一需要注意的地方就是确保数据包不超过mtu即可。典型的,对基于udp的rtp,当视频数据大于mtu时,将会将视频数据进行分包,这就是FU-A包产生的初衷。
- 应用层缓存处理的不同之处
对于tcp而言,应用层buffer的显然需要对数据进行缓存,拼接完整的数据包。
- boost asio处理tcp读操作的要点
对tcp读操作处理,通常如下:
boost::asio::async_read(mSocket, boost::asio::buffer((void*)mReceiveBuffer->data(), 4), boost::bind(&AsyncSocketBase::handleReadHeader, shared_from_this(), boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
boost::asio::buffer((void*)mReceiveBuffer->data(), 4) 例子代码中是数据包的前4个字节包含头的长度信息,所以是先读取头信息,取出整个数据包的大小,AsyncSocketBase::handleReadHeader 业务处理回调即是解析头,在handleReadHeader中绑定的异步操作如下:
boost::asio::async_read(mSocket, boost::asio::buffer(&(*mReceiveBuffer)[0], dataLen),boost::bind(&AsyncTcpSocketBase::handleReceive, shared_from_this(), boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
boost::asio::buffer(&(*mReceiveBuffer)[0], dataLen) dataLen即为通过解析头获取到的整个数据包的大小,asio将整个dataLen大小的数据包读取完后才会回调handleReceive。
- boost asio处理tcp写操作的注意点
std::vector<boost::asio::const_buffer> bufs; if(mSendDataQueue.front().mFrameData.get() != 0) // If we have frame data { bufs.push_back(boost::asio::buffer(mSendDataQueue.front().mFrameData->data(), mSendDataQueue.front().mFrameData->size())); } bufs.push_back(boost::asio::buffer(mSendDataQueue.front().mData->data()+mSendDataQueue.front().mBufferStartPos, mSendDataQueue.front().mData->size()-mSendDataQueue.front().mBufferStartPos)); boost::asio::async_write(mSocket, buffers, boost::bind(&AsyncTcpSocketBase::handleSend, shared_from_this(),boost::asio::placeholders::error);
- boost asio处理tcp和udp的不同之处及要点
- ASIO与BOOST::ASIO的不同之处
- Boost Asio 实现的UDP异步监听和TCP异步发送程序
- UDP boost::asio的实现
- UDP boost::asio的实现
- UDP boost::asio的实现
- 摘要UDP连接和TCP的不同之处初识
- boost::asio 之udp协议的使用
- boost::asio 之udp协议的使用
- boost::asio学习之[五]运行udp tcp服务
- Boost asio 同步和异步socke处理的流程
- boost中asio的tcp::iostream例子
- boost::asio tcp socket 的使用示例
- boost::asio::ip::tcp::resolver的故事
- boost::asio::tcp
- boost::asio中异步请求的实现要点
- boost::asio编程-同步UDP
- boost的asio接收单路大数据量udp包的方法
- 读源码计划
- 关于Oracle11gR2用EXP导出时报EXP-00011错误的解决方法
- maven-dependency-plugin插件的使用
- 取table首列的值
- 使用 webpack 引用 zepto
- boost asio处理tcp和udp的不同之处及要点
- ServiceLoader使用及原理分析
- java设计模式之单例模式
- 阿里云对象存储OSS配置介绍设置,上传代码示例
- 类属性与类方法
- docker安装(一)
- CSS样式之浮动
- 5.1 从键盘任意输入一个实数,不使用计算绝对值函数编程计算并输出该实数的绝对值
- python 多线程简单demo