ace nonblock

使用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
SOCK_NONBLOCK 是一个用于套接字(socket)的标志,它可以使套接字以非阻塞模式工作。 ### 定义 SOCK_NONBLOCK 是一个预定义的标志常量,用于在创建套接字时指定该套接字以非阻塞模式工作。在不同的操作系统和编译器中,该常量的定义可能有所不同,但通常在相关的头文件中被定义。 ### 使用方法 在创建套接字时,可以通过在 `socket` 函数的第二个参数中使用按位或(`|`)操作符将 SOCK_NONBLOCK 标志与其他套接字类型(如 SOCK_STREAM)组合使用。示例代码如下: ```c #include <sys/socket.h> #include <netinet/in.h> int sockfd; // 创建非阻塞的 TCP 套接字 if (defined(SOCK_NONBLOCK)) { sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); } ``` 如果系统不支持直接在 `socket` 函数中使用 SOCK_NONBLOCK 标志,也可以在创建套接字后使用 `fcntl` 或 `ioctl` 函数来设置非阻塞模式,如参考代码中所示: ```c #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> int sockfd; // 创建普通的 TCP 套接字 sockfd = socket(PF_INET, SOCK_STREAM, 0); // 获取当前套接字的标志 int flags = fcntl(sockfd, F_GETFL, 0); if (flags == -1) { flags = 0; } // 设置非阻塞标志 fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); ``` ### 作用 SOCK_NONBLOCK 的主要作用是使套接字操作以非阻塞模式进行。在非阻塞模式下,当进行一些可能会阻塞的操作(如 `recv`、`send`、`connect` 等)时,如果操作不能立即完成,函数会立即返回,而不是一直等待。这对于需要同时处理多个套接字或执行其他任务的程序非常有用,例如在网络服务器中,可以使用非阻塞套接字来实现并发处理,提高程序的性能和响应速度。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值