TCP/IP之select多路复用

select

select 函数在网络编程中用于监视多个文件描述符,查看它们是否有可读、可写或发生异常情况的条件满足。它是一种多路复用技术,使得程序可以同时监视多个文件描述符而不需要多线程或多进程。

函数原型

int select(int nfds, 
           fd_set *_Nullable restrict readfds,
           fd_set *_Nullable restrict writefds,
           fd_set *_Nullable restrict exceptfds,
           struct timeval *_Nullable restrict timeout);

参数解释

  1. int nfds:

    • 这个参数指定所有文件描述符集合中最大文件描述符值加1。即,它是集合中所有文件描述符值中的最大值加1。
    • 例如,如果 readfds 中有文件描述符 35,那么 nfds 应该是 6
  2. fd_set *readfds:

    • 一个指向 fd_set 类型的指针,用于指示要检查可读性的文件描述符集合。
    • 如果某个文件描述符在 readfds 集合中,并且在 select 调用时有数据可读,则 select 返回时,该文件描述符会保留在 readfds 集合中。
  3. fd_set *writefds:

    • 一个指向 fd_set 类型的指针,用于指示要检查可写性的文件描述符集合。
    • 如果某个文件描述符在 writefds 集合中,并且在 select 调用时可以写数据,则 select 返回时,该文件描述符会保留在 writefds 集合中。
  4. fd_set *exceptfds:

    • 一个指向 fd_set 类型的指针,用于指示要检查异常情况的文件描述符集合。
    • 如果某个文件描述符在 exceptfds 集合中,并且在 select 调用时有异常情况(如带外数据),则 select 返回时,该文件描述符会保留在 exceptfds 集合中。
  5. struct timeval *timeout:

    • 一个指向 timeval 结构的指针,用于指定 select 调用的超时时间。
    • 结构体定义如下:
      struct timeval {
          long tv_sec;  /* seconds */
          long tv_usec; /* microseconds */
      };
      
    • 如果 timeoutNULLselect 将无限期地等待,直到一个文件描述符变得可读、可写或发生异常。
    • 如果 timeout 的值为 {0, 0}select 将立即返回。

返回值

  • 成功时

    • 返回值为就绪的文件描述符的数量(即有多少个文件描述符满足了可读、可写或异常情况)。
    • 这些文件描述符会保留在相应的集合中,其他的会被移除。
  • 错误时

    • 返回 -1,并设置 errno 以指示错误原因。

示例代码

以下是一个使用 select 函数的示例,监视标准输入是否有数据可读:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>

int main() {
    fd_set readfds;
    struct timeval timeout;
    int ret;

    // 初始化文件描述符集合
    FD_ZERO(&readfds);
    FD_SET(STDIN_FILENO, &readfds);

    // 设置超时时间为5秒
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;

    // 调用select函数
    ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &timeout);

    if (ret == -1) {
        perror("select");
        exit(EXIT_FAILURE);
    } else if (ret == 0) {
        printf("Timeout occurred! No data after 5 seconds.\n");
    } else {
        if (FD_ISSET(STDIN_FILENO, &readfds)) {
            char buffer[100];
            read(STDIN_FILENO, buffer, sizeof(buffer));
            printf("Data: %s\n", buffer);
        }
    }

    return 0;
}

这个示例程序会在5秒内等待标准输入(通常是键盘)上是否有数据输入。如果有数据,它会读取并打印出来;如果5秒内没有数据输入,程序会打印超时信息并退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值