4

我是套接字编程的新手,我已经被介绍给select()系统调用。我的问题是,假设我正在用 C 语言编写服务器(我正在尝试这样做),并且我想select()在我的实现中使用该调用进行练习。我正在尝试编写一个从客户端接收信息的服务器,所以我的方法是使用select(),然后read()输出信息。

根据我读过的文档,select()返回输入集中准备好 i/o 的文件描述符的数量。我的问题是,如何知道原始集中的哪些文件描述符是为 i/o 做好准备的?我似乎无法在我过去一段时间的搜索或示例中找到它。

假设我的代码如下所示:

int main() {
/* Create socket/server variables */
    int select_value;
    int this_socket;
    int maxfd;
    struct sockadder_in address; 
    fd_set allset;

    /* Bind the socket to a port */
    main_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (main_socket < 0) {
        perror("socket()");
        exit(1);
    }

    Connect(main_socket, (struct sockaddr *)&address, sizeof(address));

    /* Add the socket to the list of fds to be monitored */
    FD_ZERO(&allset);
    FD_SET(main_socket, &allset);

    fd_set read_ready = allset;
    fd_set write_ready = allset;

    while (1) {
        /* Listen for a connection */
        /* Accept a connection */
        select_value = Select(maxfd+1, &read_ready, &write_ready, NULL, NULL);
        if (select_value == -1) {
            perror("select()");
            exit(1);
        }
        else if(select_value > 0) {
            /* How to access i/o ready file descriptors
            now that we know there are some available? */
        }
    }
} 
4

1 回答 1

4

可以使用FD_ISSET属于<sys/select.h>.

当您select解除阻塞并且文件描述符准备就绪时,您可以使用FD_ISSET宏在一个简单的循环中测试所有文件描述符。这可以翻译为以下示例:

for (i = 0; i < FD_SETSIZE; ++i) {
    if (FD_ISSET (i, &read_fd_set)) {
        if (i == bound_socket) {
            // A new client is waiting to be accepted
            new = accept(sock, (struct sockaddr *) &clientname, &size);
            // ...
            FD_SET (new, &active_fd_set);
        }
        else {
          // There is something to be read on the file descriptor.
          data = read_from_client_on(i);
        }
    }
}

当然,这只是示例,显然缺少任何错误处理,您应该在应用程序中处理。

于 2014-03-30T01:36:42.883 回答