服务器:
单循环服务器:服务器在同一时刻只能响应一个客户端的请求
并发服务器模型:服务器在同一时刻可以响应多个客户端的请求
UDP:无连接
TCP:有连接
1.多进程
资源空间消耗大
效率低
2.多线程
相对进程资源消耗小
效率较高
3.IO多路复用:
为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,
使进程不阻塞于某个特定的 I/O 系统调用。
优势:
系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程。
多进程并发服务器
多线程并发服务器
Linux系统IO模型:
1.阻塞IO
scnaf
getchar
fgets
gets
read
recv
recvfrom
1.可以实现多任务同步(多个事件相互影响)
2.可以节省CPU资源开销,提高执行效率
2.非阻塞IO
- 获取文件描述符属性
fcntl---------flag 0
-
为文件描述符添加非阻塞属性
-
设置文件描述符属性
fcntl
增加非阻塞属性
flag = fcntl(0,F_GETFL);
flag = flag | O_NONBLOCK;
fcntl(0,F_SETFL,flag);
1.可以访问多个IO事件
2.配合轮询操作,浪费CPU资源
3.信号驱动IO
1.实现异步IO操作,节省CPU开销
2.只能针对比较少的IO事件
1)为IO设备增加信号驱动属性
O_ASYNC
2)关联SIGIO信号到对应进程
fcntl(fd, F_SETOWN, getpid());
- 注册SIGIO处理函数
signal
4.多路复用IO
select
缺点:
1.select监听文件描述符最大个数为1024 (数组)
2.select监听的文件描述符集合在用户层,需要应用层和内核层互相传递数据
3.select需要循环遍历一次才能找到产生的事件
4.select只能工作在水平触发模式(低速模式)无法工作在边沿触发模式(高速模式)
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
功能:
监听文件描述符集合
参数:
nfds:监测的文件描述符上限值(最大文件描述符的值+1)
readfds:读文件描述符集合
writefds:写文件描述符集合
exceptfds:异常条件的描述符集合
timeout:设置超时时间
NULL:一直等待
返回值:
成功返回产生事件文件描述符个数
失败返回-1
定时时间到达仍没有事件产生返回0
void FD_CLR(int fd, fd_set *set);
将fd从文件描述符集合中清除
int FD_ISSET(int fd, fd_set *set);
判断文件描述符fd是否仍在文件描述符集合中
void FD_SET(int fd, fd_set *set);
将fd加入文件描述符集合中
void FD_ZERO(fd_set *set);
文件描述符集合清0
fcntl
int fcntl(int fd, int cmd, ... /* arg */ );
功能:
设置文件描述符属性
参数:
fd:文件描述符
cmd:F_GETFL 获得文件描述符属性
F_SETFL 设置文件描述符属性
返回值:
F_GETFL:
成功返回获得的属性
失败返回-1
F_SETFL:
成功返回0
失败返回-1
O_NONBLOCK 非阻塞
O_ASYNC 异步方式
修改IO属性:
1)获取原有属性
2)增加新的属性
3)设置新的属性
注意:文件属性是直接设置完成的,设置完成后就算去掉代码行,依旧会保留上一次更改设置。
select内核监听,当对应的监听内容触发后执行,大大减小了cpu的开支,以扩大服务器的容量。
使用select创建一个无进程和线程的io多路复用服务器,对多用户进行连接。