wesom 发表于 2011-3-29 11:49:26

非阻塞sock下对send数据进行的封装,抛砖引玉

//设置sock非阻塞int
Connection_Handler::open(void *p)
{
if (this->peer().enable(ACE_NONBLOCK) == -1)
    return -1;
if ( ACE_Reactor::instance()->register_handler
      (this,ACE_Event_Handler::READ_MASK) ==-1 )
    return -1;
return 0;
}//发送数据int
Connection_Handler::send(const char* buff, size_t len)
{
int empty_queue = this->msg_queue()->is_empty();
ssize_t sent = 0;
if (empty_queue)
{
    ssize_t sent =
         this->peer().send(buff, len);
    if (sent == len)
      return 0;
    if (sent == -1 && errno != EWOULDBLOCK)
      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT("(%P|%t) %p\n"),
                        ACE_TEXT("send")),
                        0);
    if (sent == -1)
      sent = 0;
}
ACE_Message_Block *mb = 0;
size_t remaining = static_cast<size_t>(len - sent);
ACE_NEW_RETURN(mb,ACE_Message_Block(&buff,remaining),-1);
ACE_Time_Value nowait(ACE_OS::gettimeofday());
if (this->putq(mb, &nowait) == -1)
{
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) %p\n"),
               ACE_TEXT("enqueue failed")));
    mb->release();
    return 0;
}
if (empty_queue)
    return this->reactor()->register_handler
                (this, ACE_Event_Handler::WRITE_MASK);
return 0;
}handle_output,handle_close,handle_input可参考书上例子,说的很清楚,只是多线程下handle_input中可能会有EWOULDBLOCK,加上如下判断if (recv_cnt == -1)
{
    if(errno != EWOULDBLOCK)
      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT("(%P|%t) %p\n"),
                        ACE_TEXT("peer failed unexpectedly")),
                        -1);
    else
      return 0;
}重点是如何send数据,如果不调用this->peer().send方法,直接放入队列,再登记写事件也是可以,但要保证是lt触发,
et下未必会及时通知写事件。
另外是单线程下使用,多线程自己加锁。

wesom 发表于 2011-3-29 11:50:11

沙发自己坐先...

lovelypp 发表于 2011-3-29 12:49:24

使用notify即可

steven99ca 发表于 2011-3-31 01:52:45

这样的封装应该在应用层。在非阻塞sock下,意义不大。

wesom 发表于 2011-3-31 09:17:39

这个就是应用层的封装
页: [1]
查看完整版本: 非阻塞sock下对send数据进行的封装,抛砖引玉