找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5213|回复: 2

Handling Events and Multiple I/O Streams handle_output 的问题

[复制链接]
发表于 2008-7-15 22:24:11 | 显示全部楼层 |阅读模式
<<The ACE programmer's guide >>
Chapter 7. Handling Events and Multiple I/O Streams

7.2 Handling Multiple I/O Sources
中有这样一段代码
int
ClientService::handle_input (ACE_HANDLE)
{
  const size_t INPUT_SIZE = 4096;
  char buffer[INPUT_SIZE];
  ssize_t recv_cnt, send_cnt;

  if ((recv_cnt = this->sock_.recv (buffer, sizeof(buffer))) <= 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P|%t) Connection closed\n")));
      return -1;
    }
  send_cnt =
    this->sock_.send (buffer, ACE_static_cast (size_t, recv_cnt));
  if (send_cnt == recv_cnt)
    return 0;
  if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("(%P|%t) %p\n"),
                       ACE_TEXT ("send")),
                      0);
  if (send_cnt == -1)
    send_cnt = 0;
  ACE_Message_Block *mb;
  size_t remaining =
    ACE_static_cast (size_t, (recv_cnt - send_cnt));
  ACE_NEW_RETURN
    (mb, ACE_Message_Block (&buffer[send_cnt], remaining), -1);
  int output_off = this->output_queue_.is_empty ();
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  if (this->output_queue_.enqueue_tail (mb, &nowait) == -1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P|%t) %p; discarding data\n"),
                  ACE_TEXT ("enqueue failed")));
      mb->release ();
      return 0;
    }
  if (output_off)
    return this->reactor ()->register_handler
      (this, ACE_Event_Handler::WRITE_MASK);
  return 0;
}

这一句“  send_cnt =
    this->sock_.send (buffer, ACE_static_cast (size_t, recv_cnt));”发送时如果没把数据发送完,会暂时存起来


7.2.3 Handling Output
int
ClientService::handle_output (ACE_HANDLE)
{
  ACE_Message_Block *mb;
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  while (0 == this->output_queue_.dequeue_head
                                    (mb, &nowait))
    {
      ssize_t send_cnt =
        this->sock_.send (mb->rd_ptr (), mb->length ());
      if (send_cnt == -1)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("(%P|%t) %p\n"),
                    ACE_TEXT ("send")));
      else
        mb->rd_ptr (ACE_static_cast (size_t, send_cnt));
      if (mb->length () > 0)
        {
          this->output_queue_.enqueue_head (mb);
          break;
        }
      mb->release ();
    }
  return (this->output_queue_.is_empty ()) ? -1 : 0;
}
中发送。
我的问题是,在handle_input时如果要发送字符串"12345",如果由于流控制,只发送了“123”,“45”暂存起来,在handle_output被调用之前,handle_input又被调用,这时又要发送"6789", 而此时网络状态恰好又是可发的了,它又把"6789"发送出去,过了一会(也许是立刻),handle_input又被调到了,此时它把"45"发送出去,

那么 最终发送出去的字符串是“123678945”,而不是“123456789”,不知道我理解的对不对。
 楼主| 发表于 2008-7-15 22:24:20 | 显示全部楼层
应该有这种可能!
发表于 2011-3-22 15:52:46 | 显示全部楼层
有,因此发送数据之前需判断消息队列是否为空
if (this->msg_queue ()->is_empty ())
    // 准备发送数据
    put(...);
  else
    // 放入队列尾
    this->msg_queue ()->enqueue_tail(...)
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-12-22 17:06 , Processed in 0.013759 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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