使用reactor, ACE_Sock_Stream进行收发数据。 nonblock模式下: [timeout参数均为NULL]
recv时, 可能返回-1. errno可能是EWOULDBLOCK(要求下次继续读), 或者其他系统错。
无需使用recv_n/send_n
ACE_Sock_Stream::recv ---->ACE::recv():
ssize_t ACE::recv (ACE_HANDLE handle, void *buf, size_t len, int flags, const ACE_Time_Value *timeout)
{
if (timeout == 0)
<span style="color:#FF0000;">return ACE_OS::recv (handle, (char *) buf, len, flags);</span>
else
{
int val = 0;
if (ACE::enter_recv_timedwait (handle, timeout, val) ==-1)
return -1;
else
{
ssize_t bytes_transferred =
ACE_OS::recv (handle, (char *) buf, len, flags);
ACE::restore_non_blocking_mode (handle, val);
return bytes_transferred;
}
}
}
ACE::recv--->ACE_OS::recv():
ACE_INLINE ssize_t ACE_OS::recv (ACE_HANDLE handle, char *buf, size_t len, int flags)
{
ACE_OS_TRACE ("ACE_OS::recv");
// On UNIX, a non-blocking socket with no data to receive, this
// system call will return EWOULDBLOCK or EAGAIN, depending on the
// platform. UNIX 98 allows either errno, and they may be the same
// numeric value. So to make life easier for upper ACE layers as
// well as application programmers, always change EAGAIN to
// EWOULDBLOCK. Rather than hack the ACE_OSCALL_RETURN macro, it's
// handled explicitly here. If the ACE_OSCALL macro ever changes,
// this function needs to be reviewed. On Win32, the regular macros
// can be used, as this is not an issue.
#if defined (ACE_LACKS_RECV)
ACE_UNUSED_ARG (handle);
ACE_UNUSED_ARG (buf);
ACE_UNUSED_ARG (len);
ACE_UNUSED_ARG (flags);
ACE_NOTSUP_RETURN (-1);
#elif defined (ACE_WIN32)
ACE_SOCKCALL_RETURN (::recv ((ACE_SOCKET) handle, buf,
static_cast<int> (len), flags), ssize_t, -1);
#else
<span style="color:#FF0000;">ssize_t ace_result_;
ace_result_ = ::recv ((ACE_SOCKET) handle, buf, len, flags);
# if !(defined (EAGAIN) && defined (EWOULDBLOCK) && EAGAIN == EWOULDBLOCK)
// Optimize this code out if we can detect that EAGAIN ==
// EWOULDBLOCK at compile time. If we cannot detect equality at
// compile-time (e.g. if EAGAIN or EWOULDBLOCK are not preprocessor
// macros) perform the check at run-time. The goal is to avoid two
// TSS accesses in the _REENTRANT case when EAGAIN == EWOULDBLOCK.
if (ace_result_ == -1
# if !defined (EAGAIN) || !defined (EWOULDBLOCK)
&& EAGAIN != EWOULDBLOCK
# endif /* !EAGAIN || !EWOULDBLOCK */
&& errno == EAGAIN)
{
errno = EWOULDBLOCK;
}
# endif /* EAGAIN != EWOULDBLOCK*/
return ace_result_;</span>
#endif /* ACE_LACKS_RECV */
}
同样, ACE_Sock_Stream::send--->ACE_OS::write---->::write