deve 发表于 2008-11-18 18:55:22

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

使用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.请问有谁知道怎么解决吗。

okibun0129 发表于 2008-11-18 18:58:49

代码再具体一点吧,
没听过proactor接收数据的时候有168字节的限制,
从这几句代码很难分析呀,

deve 发表于 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;
                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个字节则正常。

winston 发表于 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();
               
      
      }      
}

deve 发表于 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);

okibun0129 发表于 2008-11-19 09:41:28

查看一下调用堆栈,
感觉应该是别的地方错误导致的,
抑或多线程的保护出了问题,
按版主说的,
多打一些日志,
查看一下调用顺序是否出了问题也是好办法。

njf_3829 发表于 2008-12-3 07:37:05

问题解答

你发送数据后,要带Handle_write_stream 检查你的数据是否完全发过去了!
页: [1]
查看完整版本: 使用Proactor模式不能接收超过168个字节数据的问题。