套接字在非阻塞时无法接受连接?

时间:2012-07-26 16:41:58

标签: c++ sockets nonblocking vxworks

编辑:搞砸了接受调用的伪编码,它现在反映了我实际在做什么。

我有两个插座。我想在两者之间使用send / recv。当侦听套接字阻塞时,它可以看到连接并接收它。当它是非阻塞时,我会忙着等待(只是为了调试它)并且它超时,总是出现错误EWOULDBLOCK。为什么侦听套接字无法在阻塞时看到它可以看到的连接?

代码主要是在函数中分开,但这里有一些我正在做的伪代码。

int listener = -2;
int connector = -2;
int acceptedSocket = -2;

getaddrinfo(port 27015, AI_PASSIVE) results loop for listener socket
{
  if (listener socket() == 0)
  {
    if (listener bind() == 0)
      if (listener listen() == 0)
        break;
    listener close(); //if unsuccessful
  }
}
SetBlocking(listener, false);


getaddrinfo("localhost", port 27015) results loop for connector socket
{
  if (connector socket() == 0)
  {
    if (connector connect() == 0)
      break; //if connect successful
    connector close(); //if unsuccessful
  }
}

loop for 1 second
{
  acceptedSocket = listener accept();
  if (acceptedSocket > 0)
    break; //if successful
}

这只是在最终结束超时循环之前输出EWOULDBLOCK的巨大列表错误。如果我在每个循环交互中输出接受套接字的文件描述符,则永远不会为其分配文件描述符。

SetBlocking的代码如下:

int SetBlocking(int sockfd, bool blocking)
{
  int nonblock = !blocking;

  return ioctl(sockfd,
    FIONBIO,
    reinterpret_cast<int>(&nonblock));
}

如果我使用阻塞套接字,通过调用SetBlocking(listener, true)或完全删除SetBlocking()调用,连接就没有问题。

另请注意,具有相同实现的此连接适用于Windows,Linux和Solaris。

1 个答案:

答案 0 :(得分:2)

由于环路紧张,您不会让操作系统完成您的请求。这是VxWorks和其他人之间的区别 - 你基本上抢占了你的内核。

使用select(2)poll(2)代替连接。