C/S架构聊天室服务端客户端程序设计——select模型的I/O多路复用


本例要实现一个简单聊天室的服务端程序,能并发处理多个客户端的请求。具体要实现验证客户端登录,转发客户端发送的消息的功能。在此之前应该对网络编程有一定了解,熟悉socket通信的基本用法,熟悉客户端和服务端收发功能的实现方法。

问题分析

传统的socket网络编程中有很多阻塞的函数,比如accept()read()。这些函数在阻塞的时候,就不能执行其他任务,这对于服务端程序肯定是不适用的,因为一个服务端不能只服务一个客户端。我们要解决的问题就是在不同的任务到达是服务端程序可以做出不同的响应。这就是IO多路复用,Linux系统中有三种IO复用,分别是selectpollepoll。本例中选用select。

select函数

select函数可以同时监视多个套接字的可读可写状态,当状态发生变化时(例如客户端发来消息,对应套接字变成可读状态),select从阻塞状态中返回,这时程序可以根据select的返回值处理套接字。

select原型

头文件:#include <sys/select.h>
select函数的原型:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数 含义
nfds 集合中所有文件描述符的范围即所有文件描述符的最大值加1
readfds (可选)指针,指向一组等待可读性检查的套接口
writefds (可选)指针,指向一组等待可写性检查的套接口
exceptfds (可选)指针,指向一组等待错误检查的套接口
timeout select()最多等待时间,对阻塞操作则为NULL

其中阻塞时间传入的timeval结构体如下,tv_sec设置秒,tv_usec设置微秒。

struct timeval
{
   
__time_t tv_sec;        /* Seconds. */
__suseconds_t tv_usec;  /* Microseconds. */
};

第一个参数我们传入select监视的socket描述字的最大值+1;因为服务端需要监视socket可读状态发生变化,所以我们需要选择传入第二个参数readfds;select的第五个参数可以设置阻塞时间,有三种状态超时阻塞,永久阻塞和不阻塞。

参数 状态
timeval结构体 超时阻塞,超时时长为结构体设定的时长,超时或监视的socket活动时select返回
0 不阻塞,timeval的值设定为0秒0毫秒,也就是不阻塞
NULL 永久阻塞,等监视的socket状态改变时select才会返回

select原理

select会监视一个fd_set类型的数据结构,这个空间可以类比成一个数组(实际是位操作),内核通过fd_set和任意打开的描述字建立联系(网络socket描述字或文件描述字都可以),类似数组的下标和数组的元素之间的关系,数组中元素的值代表了其下标对应的描述字的状态。通过数组中指定位置为0或者1判断对应socket的活动是否发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值