找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3215|回复: 6

使用Proactor模式不能接收超过168个字节数据的问题。

[复制链接]
发表于 2008-11-18 18:55:22 | 显示全部楼层 |阅读模式
使用Proactor模式编写服务器端,在收到<=168个字节的数据一切正常,当超过168个字节后,再次调用读操作,会引起内存读写错误。错误定位到以下代码:
ACE_Asynch_Read_Stream::read (ACE_Message_Block &message_block,
                              size_t bytes_to_read,
                              const void *act,
                              int priority,
                              int signal_number)
{
  return this->implementation_->read (message_block,
                                      bytes_to_read,
                                      act,
                                      priority,
                                      signal_number);
}
implementation_指针的内容为0。我用的是ACE5.5.5 + vc6.0.请问有谁知道怎么解决吗。
发表于 2008-11-18 18:58:49 | 显示全部楼层
代码再具体一点吧,
没听过proactor接收数据的时候有168字节的限制,
从这几句代码很难分析呀,
 楼主| 发表于 2008-11-18 19:07:43 | 显示全部楼层
void TN_Pro_Service::handle_read_stream( const ACE_Asynch_Read_Stream::Result &result )
{
        LogInfo("handle_read_stream");
        ACE_Message_Block &mb = result.message_block();
       
        if (!result.success() || result.bytes_transferred() == 0)
        {       
                mb.release();
                delete this;

        }else

        {
                char temp[100];
                LogInfo("receive message[%s]",mb.rd_ptr());
                mb.release();

                if (strcmp(temp,"tian") == 0)
                {
                        ACE_Message_Block * mb1;
                        ACE_NEW_NORETURN(mb1,ACE_Message_Block(1024));

                        sprintf(mb1->wr_ptr(),"Hello Tian");

                        mb1->wr_ptr(20);
                        this->writer_.write(*mb1,1024);
                }
                cycle_read();
        }

       

}

void TN_Pro_Service::handle_write_stream( const ACE_Asynch_Write_Stream::Result &result )
{
        LogInfo("handle_write_stream");
        ACE_Message_Block &mb = result.message_block();
       
        if (!result.success() || result.bytes_transferred() == 0)
        {       
                mb.release();
                delete this;
        }else
        {
       
                mb.release();
               
       
        }       
}

void TN_Pro_Service::open( ACE_HANDLE h,ACE_Message_Block &mb )
{

        this->handle(h);

        if (this->reader_.open(*this) != 0 || this->writer_.open(*this) !=0)
        {
                delete this;
                return;
        }

        cycle_read();
}

int TN_Pro_Service::cycle_read()
{
        ACE_Message_Block *mb;
        ACE_NEW_NORETURN(mb,ACE_Message_Block(2048));

        if ( this->reader_.read(*mb,2048) != 0)
        {
                mb->release();
                delete this;

                return 1;
        }
       
        return 1;
}

问题出在cycle_read()的if ( this->reader_.read(*mb,2048) != 0)这一句上,接收超过168个字节就会出现问题,而低于168个字节则正常。
发表于 2008-11-18 21:36:23 | 显示全部楼层
上面的几个函数,都加上断点或者LOG日志调试,你程序的问题,ACE里面没有Proactor只能收取168字节的说法。
void TN_Pro_Service::handle_write_stream( const ACE_Asynch_Write_Stream::Result &result )
{
        LogInfo("handle_write_stream");
        ACE_Message_Block &mb = result.message_block();
        
        if (!result.success() || result.bytes_transferred() == 0)
        {        
                mb.release();
                delete this; //不能删除,删除只能在一个地方,一般是read
        }else
        {
        
                mb.release();
               
        
        }        
}
 楼主| 发表于 2008-11-19 08:45:41 | 显示全部楼层
是这样的,写的这个模型是收到客户端发来的数据,并打印出来,再继续读数据。数据在<=168个字节的时候完全正常。一旦大于这个168,也能收到数据,并打印,问题出在继续读数据上。

ACE_Asynch_Read_Stream reader_;
这时候变量reader_中的成员
ACE_Asynch_Read_Stream_Impl *implementation_;
implementation不知道什么原因为野指针,造成以下语句不能执行,从而使程序异常。
return this->implementation_->read (message_block,
                                      bytes_to_read,
                                      act,
                                      priority,
                                      signal_number);
发表于 2008-11-19 09:41:28 | 显示全部楼层
查看一下调用堆栈,
感觉应该是别的地方错误导致的,
抑或多线程的保护出了问题,
按版主说的,
多打一些日志,
查看一下调用顺序是否出了问题也是好办法。
发表于 2008-12-3 07:37:05 | 显示全部楼层

问题解答

你发送数据后,要带Handle_write_stream 检查你的数据是否完全发过去了!
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-6-26 20:49 , Processed in 0.015009 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表