|
最近在做ACE Proactor的东西,发现网上很多例子都说到关于ACE_Service_Handler::open方法中“伪装一个事件读完成对象”的说法。
采用类似于 ACE_Asynch_Read_Stream_Result_Impl *fake_result =
ACE_Proactor::instance ()->create_asynch_read_stream_result(...)
的办法来获得从open方法开始时就“抛”出的一些数据。
这里我来说说我的看法:
acceptor.open(ACE_INET_Addr (888), //addr_port
0, //bytes_to_read
0, //pass_address
32, //back_log
1, //reuse_addr
ACE_Proactor::instance());
注意,上面第二个参数,bytes_to_read,如果填上0,那么将不会触发在open中的“附带数据”。这样open方法的处理就可以简单些了。
另外需要补充的是。
acceptor.open(ACE_INET_Addr (888), //addr_port
0, //bytes_to_read
0, //pass_address
32, //back_log
1, //reuse_addr
ACE_Proactor::instance());
bytes_to_read选项如果填上一个非0的数字,比如填4,并不表示framework一定要读到4个字节才将结果给你。相同的,即使是只有一个字节也会将结果给你。
这里牵扯到了ACE_Message_Block,我再多说一点。
ACE_Message_Block* new_mb;
ACE_NEW_NORETURN(new_mb,ACE_Message_Block(CONST_MESSAGE_BLOCK_SIZE));
//发起一个异步读操作
if ( this->m_reader.read(*new_mb,new_mb->space()) != 0)
{
ACE_ERROR((LM_ERROR,ACE_TEXT(" (%t) error information %p.")));
new_mb->release();
delete this;
return;
}
这种代码ACE里到处可见,上面的CONST_MESSAGE_BLOCK_SIZE,指定的是缓冲区的大小,它有以下这些含义:
1:framework接收到一块数据,这块数据的大小如果小于等于 CONST_MESSAGE_BLOCK_SIZE,这时会触发一次handle_read_stream调用,将数据传递给上层处理。
2:framework接收到一块数据,这块数据的大小如果大于 CONST_MESSAGE_BLOCK_SIZE,这时会触发handle_read_stream调用,将CONST_MESSAGE_BLOCK_SIZE大小的包给你处理,你在处理结束后又来了一次m_reader.read ,framework又将剩余的数据遵循同样的规则读出。
特别注意:有人问我关于填写的这些bytes_to_read或message_block_size数字,是不是framework一定要等到收到这么多数据才将结果抛出?这是新手容易发生理解错误的地方,正确的理解是,任何时候系统都有可能将抛给你一个确定大小但不确定有效内容长度的数据块! |
|