jiamswang 发表于 2009-8-3 11:55:17

在handle_read_stream 时, 总是返回成功这是为什么(在线等)

我有一ACE做的程式, 先初始化接收. 在收到数据后,打印收到的信息. 再接收.
但程式却进入死循环. 因在handle_read_stream 这个中, 总是返回, 但BYTE_TRANSFERD=0
这如何是好呀?

int
Client::initiate_read_stream (void)
{
if (this->flg_cancel_ != 0 || this->handle_ == ACE_INVALID_HANDLE)
return -1;

ACE_Message_Block *mb = 0;
ACE_NEW_RETURN (mb,
   ACE_Message_Block (1024), //BUFSIZ + 1),
   -1);

// Inititiate read
if (this->rs_.read (*mb, mb->size ()-1) == -1)
{
   mb->release ();
   // On peer close, ReadFile will yield ERROR_NETNAME_DELETED; won't get
   // a 0-byte read as we would if underlying calls used WSARecv.
   if (ACE_OS::last_error () == ERROR_NETNAME_DELETED)
    ACE_ERROR_RETURN ((LM_DEBUG,
    ACE_TEXT ("(%t) Server %d, peer closed\n"),
    this->id_),
    -1);
}
}


void
Client::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
{
{
ACE_GUARD (ACE_SYNCH_MUTEX, monitor, this->lock_);
ACE_Message_Block & mb = result.message_block ();
if (loglevel > 1)
{
   LogLocker log_lock;
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("(%t) **** Client %d: handle_read_stream() ****\n"),
    this->id_));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %B\n"),
    ACE_TEXT ("bytes_to_read"),
    result.bytes_to_read ()));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %d\n"),
    ACE_TEXT ("handle"),
    result.handle ()));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %B\n"),
    ACE_TEXT ("bytes_transfered"),
    result.bytes_transferred ()));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %@\n"),
    ACE_TEXT ("act"),
    result.act ()));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %d\n"),
    ACE_TEXT ("success"),
    result.success ()));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %@\n"),
    ACE_TEXT ("completion_key"),
    result.completion_key ()));
   ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("%s = %d\n"),
    ACE_TEXT ("error"),
    result.error ()));
}
this->initiate_read_stream (); //再接收数据.
}

modern 发表于 2009-8-3 13:29:43

需要详细的日志信息才好分析,
handle_read_stream 里不是已经把日志打出来了么,
你把日志信息贴出来,看看result里面的东西到底是什么。

首先需要判断result.success 是否成功,如果这里就不成功。
然后再根据result里面的信息另做分析。

[ 本帖最后由 modern 于 2009-8-3 13:46 编辑 ]

jiamswang 发表于 2009-8-3 13:58:44

打印的日志如下,谢谢modern的在线支持

******** client 0 handle_read_stream() **********
byte_to_read = 1023
handle = 3768
byte_transfered = 0
act = 0000000
successed = 1
completionkey = 000000000
error = 0

在我这,这些打印消息不停的在DOS窗口扫, CPU要耗尽了.

jiamswang 发表于 2009-8-3 14:01:09

怎附代码?

我这个代码是从ACE的proactor_test 改来的, 作用是作一个nat转发. 怎附代码.

lianqin7 发表于 2009-8-3 14:25:22

在initiate_read_stream中,无论this->rs_.read (*mb, mb->size ()-1)是否成功,系统均自动调用handle_read_stream,而handle_read_stream中又没对result.success 是否成功做处理,继续调用initiate_read_stream,当然无限循环了

注意就算initiate_read_stream返回-1只要有this->rs_.read 这个调用,系统都会自动调用handle_read_stream的啊

jiamswang 发表于 2009-8-3 14:30:25

哦,原来如些, 那我想要一些接收数据, 但数据只有在 winapi 的 receive 真正收到数据后, 通知我去处理收到的数据.看来不能用 handle_read_stream 了, 那用什么回调呢

jiamswang 发表于 2009-8-3 14:33:06

我的程式与外网一直保持连接, 一直在接收数据, 只有超时才关连接. 不然一直 ws_.read().不知用ACE的什么方式来作

jiamswang 发表于 2009-8-3 14:35:44

如果用定时器或sleep 可能实时性不好. 我还以为 handle_read_stream()是在数据真正的从网络的一端读成功了一些字节才返回的回调呢

modern 发表于 2009-8-3 14:52:45

原帖由 lianqin7 于 2009-8-3 14:25 发表 http://www.acejoy.com/bbs/images/common/back.gif
在initiate_read_stream中,无论this->rs_.read (*mb, mb->size ()-1)是否成功,系统均自动调用handle_read_stream,而handle_read_stream中又没对result.success 是否成功做处理,继续调用initiate_read_stream,当然无限循环 ...

lianqin7正解

不过观看楼主的日志,success的值为1,但是bytes_transferred为0,
建议楼主检查TCP连接是否还在,如果是这种情况一般很有可能是连接关闭了。

jiamswang 发表于 2009-8-3 14:59:59

我对ACE不是太懂, 真如lianqin7 所说, 那在initiate_read_stream中,this->rs_.read (*mb, mb->size ()-1) 可不可用什么设置,使它只有在收到数据,或超时,或什么的情况下才返回呢, 那这个handle_read_stream 中的 successed=1 代表的不是真的从 sock 底层收到了数据吗?
页: [1] 2
查看完整版本: 在handle_read_stream 时, 总是返回成功这是为什么(在线等)