服务器的调度策略
网络编程
服务器的调度策略
基于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 进行设定。


(2) 多任务并发(适用于TCP协议,利用多进程或者多线程来同时处理多个套接字)
首先创建一条专门的线程处理监听套接字,用于随时监听和接受客户端的连接请求。后每当有一个客户端连接成功产生一个套接字,就分配一条线程与之对应。

(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.阻塞原因
①无超时机制
②监控中文件描述符无任何变化



浙公网安备 33010602011771号