MST

星途 面试题库

面试题:网络编程之select实现基础

在利用select实现网络通信时,描述一下fd_set数据结构的作用,以及如何使用相关函数(如FD_SET、FD_CLR等)来操作它。
31.6万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

fd_set数据结构的作用

fd_set是在Unix/Linux系统中用于select函数的一个数据结构,它用来表示一组文件描述符(file descriptor)。select函数通过检查fd_set中各个文件描述符的状态,判断哪些文件描述符已经准备好进行读、写或异常处理操作。这样可以实现同时监听多个文件描述符,提高I/O操作的效率,避免逐个轮询文件描述符带来的性能开销。

相关函数及操作方法

  1. FD_SET宏

    • 作用:将一个给定的文件描述符添加到fd_set集合中。
    • 原型void FD_SET(int fd, fd_set *set);
    • 示例
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <sys/select.h>
    
    int main() {
        fd_set read_fds;
        FD_ZERO(&read_fds);
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
            perror("socket");
            exit(1);
        }
        FD_SET(sockfd, &read_fds);
        // 后续可以使用select函数基于read_fds进行操作
        close(sockfd);
        return 0;
    }
    
  2. FD_CLR宏

    • 作用:从fd_set集合中移除一个给定的文件描述符。
    • 原型void FD_CLR(int fd, fd_set *set);
    • 示例
    // 假设之前已经设置了read_fds集合
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        exit(1);
    }
    FD_SET(sockfd, &read_fds);
    // 假设要移除sockfd
    FD_CLR(sockfd, &read_fds);
    close(sockfd);
    
  3. FD_ISSET宏

    • 作用:检查一个给定的文件描述符是否在fd_set集合中。
    • 原型int FD_ISSET(int fd, fd_set *set);
    • 返回值:如果文件描述符fd在集合set中,返回非零值;否则返回0。
    • 示例
    if (FD_ISSET(sockfd, &read_fds)) {
        // sockfd在read_fds集合中,执行相关读操作等
        char buffer[1024];
        ssize_t bytes_read = recv(sockfd, buffer, sizeof(buffer), 0);
        if (bytes_read > 0) {
            buffer[bytes_read] = '\0';
            printf("Received: %s\n", buffer);
        }
    }
    
  4. FD_ZERO宏

    • 作用:清空fd_set集合,使其不包含任何文件描述符。
    • 原型void FD_ZERO(fd_set *set);
    • 示例
    fd_set read_fds;
    FD_ZERO(&read_fds);
    // 然后可以使用FD_SET等宏添加文件描述符到read_fds集合
    

在使用select函数时,通常会初始化fd_set集合(使用FD_ZERO),添加感兴趣的文件描述符(使用FD_SET),调用select函数等待文件描述符准备好,然后通过FD_ISSET检查哪些文件描述符准备好了,进行相应的I/O操作。如果某个文件描述符不再需要监听,可以使用FD_CLR将其从集合中移除。