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

Socket can't accept connections when non-blocking?

本文关键字:连接 套接字      更新时间:2023-10-16

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

我有两个插座。我正试图在两者之间使用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的巨大列表errno。如果我在每个循环交互中为接受的套接字输出文件描述符,那么它永远不会被分配文件描述符。

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中都可以使用。

由于存在紧密的循环,您不会让操作系统完成您的请求。这就是VxWorks和其他版本的区别——你基本上抢占了你的内核。

请使用select(2)poll(2)来等待连接。