找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6937|回复: 17

关于接收失败或者接收的消息长度为0的问题,急!

[复制链接]
发表于 2008-8-7 19:18:39 | 显示全部楼层 |阅读模式
void
CAceClientHandler::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
{
{
  ACE_GUARD (ACE_SYNCH_MUTEX, monitor, this->lock_);
  CAceCCharacter * pCharacter = m_pCharacter;
  int nSuccess(0), nBytes_transferred(0);
  {
   ACE_Message_Block & mb = result.message_block ();
   nSuccess = result.success();
   nBytes_transferred = result.bytes_transferred();
   if ( nSuccess && (nBytes_transferred != 0) )
   {
    if ( !m_pRecvHeader )
    {
     m_pRecvHeader = new char[PACK_DATA_SIZE * 2];
    }
    int nThisLen = mb.length();
    if ( pCharacter && pCharacter->IsAddHeader() )
    {
     // 这里假设每次收到一个包,不会收到半包。(不知道服务器发多少字节,没有办法呀!)
     WORD wThisMsgSize   = sizeof(SMG_PK_HEADER) + (WORD)nThisLen;
     wThisMsgSize = MIN(wThisMsgSize, MAX_SMG_PK_SIZE);
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_wtype1  = SMG_PK_TYPE_GENERAL;
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_wtype2  = wThisMsgSize;
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_nPackSize = wThisMsgSize;
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_nID   = -1;
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_nConnectionID = -1;
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_nGlobalID = -1;
     ((SMG_PK_HEADER *)m_pRecvHeader)->m_aPara[0] = SMG_STOC_OTHER_NO_HEADER_RETURN;
     memcpy( SMG_PK_DATA(m_pRecvHeader), mb.rd_ptr(), nThisLen );
     m_nRecvHeaderLen = MAX_SMG_PK_SIZE; // 唉,开始胡乱搞了。
    }
    else
    {
     if ( m_nRecvHeaderLen + nThisLen > MAX_SMG_PK_SIZE * 2 )
     {
      OutputError( SMG_E_NULL, __FILE__, __LINE__, "怎么这么长!<%d>", m_nRecvHeaderLen + nThisLen );
      nSuccess = 0; // 断开吧。
     }
     else
     {
      memcpy( m_pRecvHeader + m_nRecvHeaderLen, mb.rd_ptr(), nThisLen );
      m_nRecvHeaderLen += nThisLen;
     }
    }
   }
   else
   {
    m_nRecvHeaderLen = 0;
   }
   mb.release ();
  }

  if ( nSuccess && nBytes_transferred != 0 )
  {
   if ( pCharacter )
   {
    if ( m_nRecvHeaderLen >= MAX_SMG_PK_SIZE )
    {
     pCharacter->AddRecvPack( m_pRecvHeader );
     // 往前移动一个包
     memcpy( m_pRecvHeader, m_pRecvHeader + MAX_SMG_PK_SIZE, m_nRecvHeaderLen - MAX_SMG_PK_SIZE );
     m_nRecvHeaderLen -= MAX_SMG_PK_SIZE;
    }
    this->initiate_read_stream ();
    return;
   }
   else
   {
    SMG_ASSERT(FALSE);
    OutputError( SMG_E_NULL, __FILE__, __LINE__, "pCharacter 为空!" );
   }
  }
  else
  {
   //TRACE("出错了,要关闭。\r\n");
  }
  }
  //delete this;
  SetInvalid();//这里就断开了!!!!是合理的么?如果不断开,有什么办法补救???另外为什么这里断开的很频繁??是跟网络状况有关么???
}

代码是别人写的,我自己对ACE也只是一知半解,勉强能看懂而已,希望各位大哥帮个忙,给些提示吧!很急的!
 楼主| 发表于 2008-8-7 22:47:32 | 显示全部楼层
SetInvalid();这个就是设置客户端断开的函数
发表于 2008-8-7 23:06:50 | 显示全部楼层
接收失败或者接收到0个字节,通常是对方断开了连接,不知道SetInvalid();是做什么的,猜测可能是重传或者清理等其他工作吧。
 楼主| 发表于 2008-8-8 10:53:15 | 显示全部楼层
SetInvalid();跟重传没关系的,就是清理客户端的一些资源。
发表于 2008-8-8 12:01:29 | 显示全部楼层
可能楼主没有弄清楚,那句代码只是当客户端断开时做相应处理操作。并没有说这一定是频繁发生的,客户端主动断开连接,服务端只能做清理释放资源了。
 楼主| 发表于 2008-8-8 12:07:43 | 显示全部楼层
现在的问题是当接收失败或者接收到的数据为0时,客户端就主动断开了。这样的逻辑是合理的么??如果我不想让他断开的话,有什么办法补救么??而且现在的问题是在这里确实是频繁的断开了。
发表于 2008-8-8 12:37:45 | 显示全部楼层
不是当接收失败或者接收到的数据为0时,客户端就主动断开了,而是客户端先断开,服务端才会接收失败或者接收到的数据为0。
至于客户端为什么要断开,服务端没办法知道。能有什么办法补救呢,总不能人家要断开服务端拒绝吧,呵呵。要从客户端找原因。
 楼主| 发表于 2008-8-11 10:23:59 | 显示全部楼层
上面是客户端的代码。你的意思是,造成客户端的接受失败或者接受数据为0时的原因是服务器主动断开,导致客户端接收失败或者接受数据为0的??
 楼主| 发表于 2008-8-11 10:24:34 | 显示全部楼层
不好意思,这两天跑了下图书馆。。。。没来的及回帖。抱歉
 楼主| 发表于 2008-8-11 10:59:24 | 显示全部楼层
另外如果是有一方先断开的话,那么就不会发送数据了吧,另外一端就不存在接收数据的说法了。应该是一直处在监听状态,而不会收到任何数据,那也不会有接收失败或者接收的数据为0的状态出现了
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-12-23 17:29 , Processed in 0.018307 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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