非阻塞sock下对send数据进行的封装,抛砖引玉
//设置sock非阻塞intConnection_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下未必会及时通知写事件。
另外是单线程下使用,多线程自己加锁。 沙发自己坐先... 使用notify即可 这样的封装应该在应用层。在非阻塞sock下,意义不大。 这个就是应用层的封装
页:
[1]