我有一个单线程程序。它每五秒钟向四个目的地发送消息。我不想阻止 connect()
。所以我正在这样写我的程序:
int j, rc, non_blocking=1, sockets[4], max_fd=0;
struct sockaddr server=get_server_addr();
fd_set fdset;
const struct timeval conn_timeout = { 2, 0 }; /* 2 seconds */
for (j=0; j<4; ++j)
{
sockets[j]=socket( AF_INET, SOCK_STREAM, 0 );
ioctl(sockets[j], FIONBIO, (char *)&non_blocking);
connect(sockets[j], &server, sizeof (server));
}
/* prepare fd_set */
FD_ZERO ( &fdset );
for (j=0;j<4;++j)
{
if (sockets[j] != -1 )
{
FD_SET ( sockets[j], &fdset );
if ( sockets[j] > max_fd )
{
max_fd = sockets[j];
}
}
}
rc=select(max_fd + 1, NULL, &fdset, NULL, &conn_timeout );
if(rc > 0)
{
for (j=0;j<4;++j)
{
if(sockets[j]!=-1 && FD_ISSET(sockets[j],&fdset))
{
/* send() */
}
}
}
/* close all valid sockets */
但是,select()
似乎在 ONE 文件描述符准备就绪后立即返回,而不是阻塞 conn_timeout
(2 秒)。那么在这种情况下,我该如何实现我的目标呢?
- 如果所有套接字都准备就绪,程序将继续。
- 如果任何一个套接字没有准备好,程序可以在那里阻塞 2 秒。
最佳答案
是的,select
的设计假设是您希望在每个套接字就绪后立即为其提供服务。
如果我明白你想做什么,那么完成它的最简单方法就是在 fdset 准备就绪时从 fdset 中删除每个套接字。如果集合中还有剩余的套接字,则使用gettimeofday
向下调整超时,然后再次调用select
。当集合为空时,所有四个 socket 都可用,您可以继续。
关于c - 选择多个非阻塞连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16257456/