Linux网络编程中select函数的用法和原理:
用法: 功能:select函数用于检测一组socket中是否有事件就绪,这些事件可以分为三类:读就绪、写就绪和异常。 参数: readfds:指向fd_set结构的指针,用于监视读就绪的socket。 writefds:指向fd_set结构的指针,用于监视写就绪的socket。 exceptfds:指向fd_set结构的指针,用于监视异常事件。 timeout:指定等待的最长时间,为timeval结构。若设为NULL,则select将阻塞直到有文件描述符就绪。 返回值:返回值为就绪的文件描述符总数,若出错则返回1。
原理: fd_set结构体:fd_set是一个位图结构,用于存储一组文件描述符。每个文件描述符对应位图中的一个位,通过位操作可以高效地添加、删除和检查文件描述符。 位图法:在Linux上,fd_set采用位图法确定文件描述符的位置。具体来说,FD_SET宏将一个文件描述符对应的位在fd_set中置1,表示该文件描述符已加入监视集合;FD_CLR宏则将其置0,表示从监视集合中删除。 事件监视:select函数通过监视readfds、writefds和exceptfds中的文件描述符,判断哪些文件描述符上有读、写或异常事件发生。一旦有事件发生,select函数将返回就绪的文件描述符总数,并可以通过位操作检查哪些文件描述符就绪。 时间限制:select函数的等待时间由timeout参数指定。若timeout为NULL,则select将阻塞直到有文件描述符就绪;若timeout指定的时间到达而没有任何文件描述符就绪,则select返回0。
注意: fd_set中可存储的文件描述符数量有限,这在处理大量并发连接时可能不够用。 select函数在处理大量文件描述符时效率较低,因为每次调用都需要遍历整个fd_set。对于高并发场景,可以考虑使用poll或epoll等更高效的替代方案。
❷ linux网络编程(三)-bind()剖析
今天我们将深入探讨bind()函数,它在Linux网络编程中扮演着关键角色。其基本功能是将一个socket与特定的IP地址和端口绑定,以便客户端的连接请求能与其关联起来。
在服务端,bind()是强制性的,因为它确保了服务器的监听地址明确。而对于客户端,bind()并非强制,如果不指定,系统会自动为socket分配一个本地地址和端口进行绑定。
bind()函数接收以下参数:socket文件描述符(sockfd),一个包含IP地址和端口的struct sockaddr结构体,以及该结构体的长度(address_len)。成功时返回0,失败则返回-1,并通过errno设置错误信息。
值得注意的是,早期的协议地址类型已发展为IPV4和IPV6,这促使对sockaddr结构体的更新。例如,要绑定一个IPv4地址,需要相应地构造地址参数。
在内核层面,bind()的实现涉及如下步骤:首先,通过fd找到与之关联的socket实例。然后,对提供的地址和端口参数进行有效性检查。最后,将这些参数值赋给socket实例中的相关成员。
总的来说,bind()函数的工作相对直接且明确,主要包括:根据提供的描述符获取socket实例,验证地址和端口参数,以及配置socket实例的内部数据结构。