服务器的调度策略

网络编程

服务器的调度策略

基于UDP实现

UDP协议不需要连接,只需要一个套接字便可与任意个客户端通信,但是当客户端没有发来消息的时候,服务端如果调用 recvfrom() 将会进入阻塞。

基于TCP实现

每当有一个远端的客户端发起连接成功后,服务端这边都会新增一个已连接套接字。当一个服务端网络程序需要同时处理多个套接字时,应采取什么样的服务器的调度策略。

服务器的调度策略(提高IO输入输出的性能)

(1) 非阻塞轮询(适用于UDP,套接字为非阻塞状态,循环recv读取数据,无论是否读到都返回)

方法一:在socket函数的第二个参数中位与上SOCK_NONBLOCK(用于高版本linux系统)

eg.socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,0);

方法二:fcntl函数:int fcntl(int fd, int cmd);
1.参数

int fd(需要设置或者获取属性的套接字)

int cmd()(cmd参数F_GETFL(void)或者为F_SETFL(void))

2.返回值

取决于第二个参数,若是F_GETFL(void),返回值为文件描述符标志;若是F_SETFL(void),返回值为文件状态标志。

3.注意

fcntl()函数可以设置或者获取套接字文件的属性。

为了防止套接字文件的原有属性被破坏,所以一定要先用 F_GETFL 获取套接字已有属性,然后通过位或运算加上非阻塞属性O_NONBLOCK,然后再用 F_SETFL 进行设定。
image
image

(2) 多任务并发(适用于TCP协议,利用多进程或者多线程来同时处理多个套接字)

首先创建一条专门的线程处理监听套接字,用于随时监听和接受客户端的连接请求。后每当有一个客户端连接成功产生一个套接字,就分配一条线程与之对应。

image

(3) 异步信号(适用于UDP协议,用信号来处理多个套接字)

在使用信号时默认状态会杀死目标进程,因此使用SIGIO时必须要设定其响应函数。

(4) 多路复用(资源有限情况下适合使用,通过select()或poll()来同时监听多路阻塞IO)

select函数:int select(int nfds,fd set *readfds, fd set *writefds.fd set exceptfds,struct timevaltimeout);
1.参数

int nfds(集合中就绪状态的文件描述符的最大值 + 1)

fd_set *readfds(读就绪状态,不需要则填NULL)

fd_set *writefds(写就绪状态,不需要则填NULL)

fd_set *exceptfds(执行就绪状态,不需要则填NULL)

struct timeval *timeout(超时机制)

2.返回值

状态改变的文件描述符的值

3.注意

*当 select() 结束返回时,三个集合中未处于就绪状态的套接字将被自动清零,因此需要在下一次使用前再将文件描述符放入集合中*

4.阻塞原因

①无超时机制

②监控中文件描述符无任何变化
image
image

posted @ 2024-06-11 02:10  luxiaolim  阅读(50)  评论(0)    收藏  举报