找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5656|回复: 12

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

[复制链接]
发表于 2009-8-3 11:55:17 | 显示全部楼层 |阅读模式
我有一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 = [url=]%@\n[/url]"),
    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 = [url=]%@\n[/url]"),
    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 (); //再接收数据.
}
发表于 2009-8-3 13:29:43 | 显示全部楼层
需要详细的日志信息才好分析,
handle_read_stream 里不是已经把日志打出来了么,
你把日志信息贴出来,看看result里面的东西到底是什么。

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

[ 本帖最后由 modern 于 2009-8-3 13:46 编辑 ]
 楼主| 发表于 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要耗尽了.
 楼主| 发表于 2009-8-3 14:01:09 | 显示全部楼层

怎附代码?

我这个代码是从ACE的proactor_test 改来的, 作用是作一个nat转发. 怎附代码.
发表于 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的啊
 楼主| 发表于 2009-8-3 14:30:25 | 显示全部楼层
哦,原来如些, 那我想要一些接收数据, 但数据只有在 winapi 的 receive 真正收到数据后, 通知我去处理收到的数据.看来不能用 handle_read_stream 了, 那用什么回调呢
 楼主| 发表于 2009-8-3 14:33:06 | 显示全部楼层
我的程式与外网一直保持连接, 一直在接收数据, 只有超时才关连接. 不然一直 ws_.read().  不知用ACE的什么方式来作
 楼主| 发表于 2009-8-3 14:35:44 | 显示全部楼层
如果用定时器或sleep 可能实时性不好. 我还以为 handle_read_stream()是在数据真正的从网络的一端读成功了一些字节才返回的回调呢
发表于 2009-8-3 14:52:45 | 显示全部楼层
原帖由 lianqin7 于 2009-8-3 14:25 发表
在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连接是否还在,如果是这种情况一般很有可能是连接关闭了。
 楼主| 发表于 2009-8-3 14:59:59 | 显示全部楼层
我对ACE不是太懂, 真如lianqin7 所说, 那在initiate_read_stream中,this->rs_.read (*mb, mb->size ()-1) 可不可用什么设置,使它只有在收到数据,或超时,或什么的情况下才返回呢, 那这个  handle_read_stream 中的 successed=1 代表的不是真的从 sock 底层收到了数据吗?
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-11-22 23:56 , Processed in 0.116103 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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