一、循环服务器
一个服务器同一时刻只能响应一个客户端的请求。
(1)TCP循环服务器
服务器运行后等待客户端的连接请求
服务器接受一个客户端的连接后开始处理,完成客户的所有请求后断开连接
循环服务器一次只能处理一个客户端的请求
只有在当前客户的所有请求都完成后,服务器才能处理下一个客户的连接/服务请求
如果某个客户端一直占用服务器资源,那么其他的客户端不能被处理,TCP服务器一般很少采用循环服务器。
TCP循环服务器的流程如下:
socket();
bind();
listen();
while(1){
accept();
while(1){
recv();
process();
send();
}
close();
}
(2)UDP循环服务器
UDP服务器每次从套接字读入一个客户端的请求,处理后将结果返回给客户机
UDP循环服务器的例程如下:
socket();
bind();
while(1){
recvform();
process();
sendto();
}
close();
二、并发服务器
(1)TCP并发服务器
为了弥补TCP循环服务器的缺陷,并发服务器的设计思想是服务器接收客户端的连接请求后,创建子进程来为客户端服务
避免了循环服务器中客户端独占服务器的情况
为了响应客户端的请求,服务器创建子进程来处理。如果多个客户端连接,就创建多个子进程,过多的子进程会影响客户端的运行效率。
TCP并发服务器的流程如下:
socket();
bind();
listen();
while(1){
accept();
if(fork()==0){
while(1){
recv();
process();
send();
}
close();
exit(0);
}
close();
(2)UDP并发服务器
人们把并发概念用到UDP上,就得到了UDP并发服务器模型
与TCP相同,它也是创建一个子进程来处理客户端的请求。
除非UDP服务器在处理某个客户端的请求时所用的时间较长,人们实际上较少用这种模型
三、IO模型
(1)阻塞IO
最常用、最简单、效率最低
阻塞IO是最普遍使用的IO模型,大部分程序使用的都是阻塞模式IO,缺省情况下,套接字建立后所处于的模式就是阻塞IO模式。
read、recv、recvfrom、write、send、accept、connect函数在调用是都会发生阻塞
(2)非阻塞IO
可防止进程阻塞在IO操作上,需要轮询。
将套接字设置为非阻塞模式,就相当于告诉系统内核:我请求的IO操作不能马上完成时,直接返回给一个错误给我。别进入休眠状态。当一个应用程序使用了非阻塞模式,它需要使用一个循环来不停的测试是否一个文件描述符有数据可读(polling)。应用程序不停的polling内核来检查是否IO操作已经就绪。这将是一个及其浪费CUP资源的操作。因此此模式的使用不普遍。
(3)多路复用IO
允许同时对多个IO进行控制
应用程序中同时处理多路输入输出流,如果采用阻塞模式,就无法达到目的。采用非阻塞模式需要轮询,又很浪费CPU。如果设置多个进程来分别处理一条数据通路,将新产生进程间的通信问题,是得程序极其复杂。
于是IO多路复用出现,其思想为:
先构造一张有关描述符的表,然后调用一个函数。当这些文件描述符中的一个或者多个已经准备好进行IO时,函数返回。
函数返回时,告诉进程那个描述符已经就绪,可以进行IO操作。而描述这张表的函数就是select函数
select函数:
#include
#include
#include
#include
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
功能
阻塞,当他维护的文件描述符集合中的任意一个描述符有数据发生变化,,就会立刻返回.然后去判断集合中哪个文件描述符发生了变化
参数
int nfds 维护的文件描述符中最大的值+1
fd_set *readfds 读集合
fd_set *writefds 集合
fd_set *exceptfds
struct timeval *timeout NULL 一直阻塞 =0 非阻塞 >0 超时时间
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
void FD_CLR(int fd, fd_set *set); 从set中删除fd
int FD_ISSET(int fd, fd_set *set); 判断fd是否发生了变化
void FD_SET(int fd, fd_set *set); 将fd加入到set这个集合中
void FD_ZERO(fd_set *set); 清空
四、多路复用IO 的模型框图
五多线程并发服务器的模型框图