peakzhang 发表于 2008-7-15 22:24:11

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

<<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;
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, 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”,不知道我理解的对不对。

peakzhang 发表于 2008-7-15 22:24:20

应该有这种可能!

wesom 发表于 2011-3-22 15:52:46

有,因此发送数据之前需判断消息队列是否为空
if (this->msg_queue ()->is_empty ())
    // 准备发送数据
    put(...);
else
    // 放入队列尾
    this->msg_queue ()->enqueue_tail(...)
页: [1]
查看完整版本: Handling Events and Multiple I/O Streams handle_output 的问题