当我在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;
Run Code Online (Sandbox Code Playgroud)
很棒的问题:-).这就是为什么我认为这种情况正在发生.标准说明了这一点:
如果连接不能建立直接和O_NONBLOCK设置为套接字的文件描述符,连接()失败,将errno设置为[EINPROGRESS]
问题当然是"立即"意味着什么.我认为,"立即"实际上是一些小的时间允许SYN
,SYN-ACK
,ACK
的情况发生.如果它没有等待,它将有0次实际成功的机会.
所以基本上:
SYN
SYN-ACK
.这样做会成功返回而不是EADDRINUSE
.
现在,当使用线程时,每个线程都这样做,所以没有人等待.它们只是connect(2)
和上下文切换允许每个人几乎同时完成它.