Windows网络编程之select模型(二)

发布时间 2023-09-27 22:33:40作者: TechNomad

一、select模型的特点

select 函数通常用于多路复用(multiplexing)操作,允许你同时监视多个套接字(sockets)的状态,并在其中任何一个套接字准备好进行 I/O 操作时进行响应。

以下是 select 模型的特点和作用:

  1. 并发处理多个套接字: select 允许你同时监视多个套接字的状态,例如可读、可写、出错等,而不需要为每个套接字创建一个独立的线程。这使得在一个单独的线程中能够有效地管理多个连接。

  2. 事件驱动: select 是事件驱动的,它会阻塞等待套接字上的事件发生,例如数据可读或可写。一旦有事件发生,它会通知你,你可以采取适当的操作响应这些事件。

  3. 跨平台: 尽管 select 最初是在 Unix 系统中引入的,但它也在 Windows 中提供支持。

实现原理:

  • 每个客户端都有socket,服务器也有自己的socket,将所有的socket装进一个数组结构中,即数组,通过select函数遍历数组中的socket数组,当某个socket有响应时,select就会通过其参数/返回值反馈出来
  • 如果检测到的是服务器socket,那么就是有客户端链接。
  • 如果检测到的是客户端socket,那么就是客户端请求通信。

二、select函数

函数原型:

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

参数介绍:

  1. nfds:表示最大套接字描述符(socket descriptor)加1的值。在 Windows 中,这个参数通常设置为要监视的最大套接字描述符的值加1。

  2. readfds:一个指向 fd_set 结构体的指针,用于指定要监视可读事件的套接字集合。你可以使用 FD_ZEROFD_SET 宏来设置和清除套接字集合中的套接字。

  3. writefds:一个指向 fd_set 结构体的指针,用于指定要监视可写事件的套接字集合。

  4. exceptfds:一个指向 fd_set 结构体的指针,用于指定要监视异常事件的套接字集合。

  5. timeout:一个指向 struct timeval 结构体的指针,用于设置超时时间,以毫秒为单位。如果设置为 NULLselect 将会一直阻塞,直到有套接字就绪或出现错误。如果设置为 0select 将立即返回,用于轮询套接字状态。

返回值:

  • 如果 select 函数成功,它将返回可读、可写或异常事件的套接字数量,即就绪的套接字数量。
  • 如果发生错误,select 返回 SOCKET_ERROR,你可以使用 WSAGetLastError 函数获取详细的错误码。