c - 选择多个非阻塞连接

标签 c sockets

我有一个单线程程序。它每五秒钟向四个目的地发送消息。我不想阻止 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 秒)。那么在这种情况下,我该如何实现我的目标呢?

  1. 如果所有套接字都准备就绪,程序将继续。
  2. 如果任何一个套接字没有准备好,程序可以在那里阻塞 2 秒。

最佳答案

是的,select 的设计假设是您希望在每个套接字就绪后立即为其提供服务。

如果我明白你想做什么,那么完成它的最简单方法就是在 fdset 准备就绪时从 fdset 中删除每个套接字。如果集合中还有剩余的套接字,则使用gettimeofday 向下调整超时,然后再次调用select。当集合为空时,所有四个 socket 都可用,您可以继续。

关于c - 选择多个非阻塞连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16257456/

相关文章:

c - qemu 跟踪哪些指令?

web-services - 物联网设备如何连接到服务器

c++ - 通过 Win32 应用程序从 C/C++ 中的 UDP 端口读取

php - symfony 发生错误:通知:未定义的属性:::$容器

php - websocket的服务器端需要什么?

c++ - int fun(void **args) 并在调用函数时传递参数 fun(args),

c - 如何使用 gtk3 在 gtk_dialog 窗口中打包小部件

c - 如何从 C 字符串中提取数字?

python - TCP 非阻塞 socket.connect() 和 socket.recv() 错误问题。 (Python 或 C)

c - 使用 printf 的可变长度空间