接受多个客户端连接时如何设置TCP服务器超时

时间:2019-05-18 06:23:37

标签: c select tcp server timeout

我正在使用我的TCP服务器中的一个功能,该功能在定义的时间段内(我现在将其设置为10秒)接受预定数量的客户端连接,并在达到预定数量的连接时返回。我正在使用select函数使服务器超时,但是由于某些原因,每次客户端加入时,超时都会重置。例如,如果客户端在5秒钟后加入服务器,则超时将重置并从10开始再次倒计时。非常感谢您的帮助。

我正在使用mac,我认为在此OS上,FD_ISSET用于检查客户端是否已连接(我很确定在Linux上不需要)。因此,您可以像对待linux上select函数的返回值一样对待该函数的返回值。

while (num_conn < NO_OF_CLIENTS) {

    // Listen for clients
    err = listen(server_fd, 128);
    if (err < 0) {
        fprintf(stderr, "Could not listen on socket\n");
        exit(EXIT_FAILURE);
    }
    // Zero out memory for the client information
    memset( & client, 0, sizeof(client));

    socklen_t client_len = sizeof(client);
    FD_ZERO( & set);
    FD_SET(server_fd, & set);

    select(server_fd + 1, & set, NULL, NULL, & timeout);

    // server times out after allowing 30 seconds for clients to join.
    // If no clients join function returns 0. Otherwise returns no_clients
    nready = FD_ISSET(server_fd, & set);
    printf("nready is: %d\n", nready);

    if (nready == 0) {
        return num_conn; // returns number of connections if a time out occurs. 
    }

    // Accept the connection from the client
    client_fd[num_conn] = accept(server_fd, (struct sockaddr * ) & client, & client_len);
    if (client_fd < 0) {
        fprintf(stderr, "Could not establish new connection\n");
        // SEND REJECT??
        exit(EXIT_FAILURE);
    }

    // Assign value to number of clients here and let it set after a time out
    // more work to  be done here
    printf("Accepted connection from client %d\n", num_conn);
    num_conn++;
}

1 个答案:

答案 0 :(得分:1)

select(server_fd + 1, & set, NULL, NULL, & timeout);

您的代码依赖于选择修改循环外设置的timeout,以便timeout反映剩余时间。但是您不能依赖此行为,因为它仅适用于某些平台,例如Linux。

特别是在您的平台MacOS上,man page of select明确指出超时没有以您依赖的方式更改:

  

...要进行民意调查,超时参数应为        非零,指向零值timeval结构。 超时不是        由select()更改,并且可以在后续调用中重用,但是        在每次调用select()之前重新初始化它的好方法。

这意味着您必须自己计算在select中花费的时间,并在再次调用timeout时相应地调整select