:
一、阻塞模型
一个单进程accept阻塞,接收到客户端请求后,read消息,处理write返回,而后循环继续accept。
这种模型最最简单,不实际,没什么实际用途,对于新手教学还行。
二、多进程(线程)模型
主进程循环accept阻塞,接收到客户端请求后,fork子进程处理,子进程read阻塞,接收客户端消息并响应。
这种模型是我使用到最多的,简单实用,可是当客户端请求超多时,fork子进程多,系统资源消耗大,效果不理想;固然这种与多线程同理。
三、进程池(线程池)
主进程产生固定多的子进程,并定时监控子进程状态,初始子进程都为空闲状态。子进程在accept到客户端请求,通知主进程我很忙,而后处理请求,请求处理完成后,通知主进程我很闲。主进程主要监控子进程是否僵死或退出,维护进程池固定数量的进程来处理消息。
这种模型,可能每一个人的实现方式不同,这是我接触到的。优势是:不会产生超多的进程(线程)以致于过多消耗资源,在请求数量很少的状况下,效果还好;缺点是:由于是‘池’都有限制,当远远超过进程池限制的进程数,效果并不理想。
四、链接池
这种实现方式我第一次据说,在网上查了很久也没有头绪。在个人理解里,socket都是客户端向服务端发请求创建socket链接,由于客户端不一样这种链接怎么重用?请高手指点一二,主要讲清原理便可。
五、select事件模型
这种实现方式是主进程将socket监听链接和client请求链接一块儿FD_SET到一个内核队列中,内核一直检查这个队列的哪一个socket描述符有读或写或异常的响应则通知用户进程。用户进程检测到socket监听链接有响应,则accept与客户端创建链接,并把新的client请求链接FD_SET到内核队列中;若是检测到client请求链接有响应,则fork子进程,read客户端消息,处理并响应消息。
这种模型,select会捕获到你设置的某个socket描述符有可读可写或异常的事件,可是程序员须要本身检查本身设置的全部描述符,以确认是哪一个描述符有事件发生。优势:占用资源少,不会消耗太多的cpu;缺点是select的效率和FD_SET到内核队列中的描述符的个数有关,当须要检测的描述符过多时,就要花费过多的时间去检测全部的描述符是否有时间发生,并且能够FD_SET的描述符内核也有限制,当客户端请求成千上万时,select便无能为力。
六、epoll事件模型
这种模型我刚开始接触,目前尚未彻底使用或练习过。可是实现方式倒是目前最好的一种模型,对设置监测的socket描述符同时设置回调函数,当内核监测到socket描述符有事件发生,则会主动触发回调函数。
这种模型,优势:能够接收任意多的链接,高效率,低消耗,稳定易使用;缺点:由于各系统提供的接口有很大的差别,可移植性差。
以上是我了解到的socket编程模型,欢迎跟你们讨论。同时对于第四种链接池的模型,我很不明白,但愿有高手能帮我解惑。