//设置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[sent],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下未必会及时通知写事件。
另外是单线程下使用,多线程自己加锁。 |