为什么非阻塞套接字连接速度如此之慢?

时间:2011-07-18 08:44:37

标签: c sockets

当我在1个线程中进行100个非块套接字连接时,它非常慢(连接数逐个增加),但是如果我在100个并行线程中进行阻塞套接字连接(每个线程一个连接),它非常快(立即完成)

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fcntl(sock, F_SETFL,O_NONBLOCK)!=0)
{
 perror("fcntl nonblock");
 return -1;
}

if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,&reuseAddr, sizeof(reuseAddr))!=0)
{
  perror("reuse addr");
  return -1;
}

sAddr.sin_addr.s_addr = inet_addr(SRV_ADDR);
sAddr.sin_port = htons(1972);

if ((n=connect(sock, (const struct sockaddr *) &sAddr, sizeof(sAddr))) < 0) 
{
  if (errno !=EINPROGRESS) {
      perror("client connect error");
      return -1;
  }     
}
else if (n>=0)
{
  printf("#%d connected\n",sock);
}

return sock;

1 个答案:

答案 0 :(得分:5)

很棒的问题:-)。这就是为什么我认为这种情况正在发生。标准说明了这一点:

  

如果无法建立连接立即,则O_NONBLOCK为   设置为套接字的文件描述符,connect()将失败   将errno设置为[EINPROGRESS]

当然,问题是“立即”意味着什么。我认为“立即”实际上是允许SYNSYN-ACKACK发生的一小段时间。如果它根本没有等待,它将有0次实际成功的机会。

基本上是这样的:

  • 客户端发送SYN
  • 等待(阻止)SYN-ACK的一小段时间(“立即”)。
  • 完成连接

这样做会成功返回,而不是EADDRINUSE

现在,当使用线程时,每个线程都这样做,所以没有人等待。它们都只是connect(2)并且上下文切换允许每个人几乎同时完成它。