boost官方文档中聊天程序连续发包崩溃问题

news/2025/2/22 4:37:13

大家都知道boost官方提供的聊天程序模型,由于工作需要我在上面的基础上增加图片发送的需求。发生崩溃原因。这个是发送消息的源码:

  1. void do_write(chat_message msg)  
  2.   {  
  3.     bool write_in_progress = !write_msgs_.empty(); //空的话变量为false  
  4.     write_msgs_.push_back(msg); //把要写的数据push至写队列  
  5.     if (!write_in_progress)//队列初始为空 push一个msg后就有一个元素了  
  6.     {  
  7.       boost::asio::async_write(socket_,  
  8.           boost::asio::buffer(write_msgs_.front().data(),  
  9.             write_msgs_.front().length()),  
  10.           boost::bind(&chat_client::handle_write, this,   
  11.             boost::asio::placeholders::error));  
  12.     }  
  13.   }  
  14.   
  15.   void handle_write(const boost::system::error_code& error)//第一个消息单独处理,剩下的才更好操作  
  16.   {  
  17.     if (!error)  
  18.     {  
  19.       write_msgs_.pop_front();//刚才处理完一个数据 所以要pop一个  
  20.       if (!write_msgs_.empty())    
  21.       {  
  22.         boost::asio::async_write(socket_,  
  23.             boost::asio::buffer(write_msgs_.front().data(),  
  24.               write_msgs_.front().length()),  
  25.             boost::bind(&chat_client::handle_write, this,  
  26.               boost::asio::placeholders::error)); //循环处理剩余的消息  
  27.       }  
  28.     }  

每次发送消息都是调用do_write函数,write_msgs_是保存消息的队列。表面上看是没有什么问题。但是当你连续调用这个函数的时候就会出现问题。因为频繁调用和各种对调函数。会出现write_msgs_.front()中write_msgs_队列为空崩溃。目前解决方法是加锁。确保pop_front()、push_back()函数不出现连续调用使front()函数调用崩溃问题。我不知道又没用更好的办法。希望大家能给我更好的意见,下面是我的源码:

void do_write(Message_Base msg)
{
boost::mutex::scoped_lock lock(mtx);
if (msg.data() !=NULL )
write_msgs_.push_back(msg); //把要写的数据push至写队列  


if (!write_msgs_.empty())//队列初始为空 push一个msg后就有一个元素了  
{
Message_Base Info = write_msgs_.front();
boost::asio::async_write(socket_,
boost::asio::buffer(Info.data(),
Info.length()),
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error));
}
}


void handle_write(const boost::system::error_code& error)//第一个消息单独处理,剩下的才更好操作  
{
boost::mutex::scoped_lock lock(mtx);
if (!error)
{
if (!write_msgs_.empty())
write_msgs_.pop_front();//刚才处理完一个数据 所以要pop一个  
if (!write_msgs_.empty())
{
Message_Base Info = write_msgs_.front();
boost::asio::async_write(socket_,
boost::asio::buffer(Info.data(),
Info.length()),
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error)); //循环处理剩余的消息  
}
}
else
{
if (m_pCallBackTimeOut)
m_pCallBackTimeOut(RESULT_ERROR, (char*)error.message().c_str());
do_close();
}
}

http://www.niftyadmin.cn/n/1460879.html

相关文章

Centos7---查看内存型号

1.dmidecode sudo dmidecode -t memory 1这里也可以把查询的信息输出到特定的文件上去,下面是折腾出来的记录# dmidecode 2.12 SMBIOS 2.6 present.Handle 0x0019, DMI type 16, 15 bytes Physical Memory ArrayLocation: System Board Or MotherboardUse: System MemoryErr…

关于环形缓冲区的使用

前一段时间在做视频接收的时候,自己写了一个很简单的环形缓冲区例子,参照了ffmpeg AVFifoBuffer类,但是又简化了这个类,并增加一个内存映射链表,用来动态移动读指针。现在我来介绍一下具体原理。 其实环形缓冲区就是…

堆栈溢出引出的一些mark知识点--汇编

0x01缘由 浏览博客时,发现一篇《CVE-2016-10190 FFmpeg Heap Overflow 漏洞分析及利用》传送:https://security.tencent.com/index.php/blog/msg/116?utm_sourcetuicool&utm_mediumreferral,因为从事C/C编程,带着兴趣和疑问阅…

常用HTTP协议响应码

HTTP响应码,也称http状态码(HTTP Status Code),反映了web服务器处理HTTP请求状态,每一个响应码都代表了一种服务端反馈的响应状态,标识了本次请求是否成功。我们应该了解常见的响应码代表的状态,通过响应码能够对错误进行排查和定位,这是一个测试的必备技能~HTTP响应码通…

详解EVENTLOGRECORD结构体遇到的问题

如何获取电脑的各种事件信息,我相信随便一搜索就都知道了,这样的帖子很多,但是他们的例子很多根本获取不到事件的详细信息。ReadEventLog获取具体事件信息,我就不做过多讲述了,很多帖子都有使用方法,下面我…

shell 脚本之 curl 请求

shell 脚本之 curl 请求 这篇我们介绍一下怎样利用 shell 的功能去封装一个 curl 的请求并把请求的结果做个初步的判断这个只是个最简单的,如果有需要可以在这个基础上进行各种其他的判断,结合一些其他的工具对网站进行监控。 执行脚本: sh…

C++获取浏览器浏览历史(兼容谷歌、IE、火狐)

我参考:http://blog.csdn.net/anda0109/article/details/41385241 贴写但是发现很多问题,我就在这个类的基础上重新写的代码,来完成获取浏览器记录,代码如下: #pragma onceenum HistorySource {HistorySource_IE,HistorySource_Ch…

Linux-RedHat7.2 使用CentOS源

-- 查看yum rpm -qa |grep yum --卸载yum rpm -qa | grep yum | xargs rpm -e --nodeps --拷贝centos系统yum工具安装程序到linux指定目录下 wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/yum-3.4.3-132.el7.centos.0.1.noarch.rpm wget http://vault.cent…