Windows下的网络模型
Windows下的网络模型
同步阻塞+多线程模型
每个线程服务一个客户, 受到线程数量的限制
同步非阻塞
创建一个线程, 将socket设置为非阻塞, 遍历所有的socket
频繁地进入内核每次仅仅查看一个socket
select模型
https://blog.csdn.net/yxtxiaotian/article/details/84062446
一次可以处理的socket最多处理1024个(windows平台), 可以跨平台。
将所有socket交给select统一在内核中查看, 可以设置等待时长
select是阻塞的, 在内核中查看socket集合和拷贝socket时, 以及recv和send。
异步选择和事件选择模型
异步选择是将每一个socket绑定一个事件event, 通过查看event是否有事件来进行处理。
1. 相比于select:select查看socket集合、拷贝socket的过程是阻塞的, 异步事件将event置为有事件的过程(异步选择发送消息的过程)是异步的, 不会阻塞
2. select不仅在select函数处阻塞, 还在recv和send处阻塞, 异步事件和异步选择同理也是阻塞的。
异步事件:
1. 单次只能查看64个事件, 可以通过每次查看一个事件来增加处理的数量(外面加一个循环)。
2. 用多线程进行优化, 不好管理, 如果多个客户端都对应一个线程所等待的事件, 而其他线程都没有事情做, 效率就相当于单线程。
3. 事件过多的话, 处理的过程是无序的, 不能做到谁先来就处理谁, 只能按数组遍历处理。
异步选择对比异步事件:
1. 使用的是操作系统的内部消息队列, 是有序的
2. 整个消息队列都是系统维护的, 我们只需要取出消息进行处理即可
重叠IO
基于基本的cs模型进行的优化
1. 将每一个socket绑定一个重叠结构, 重叠结构中有一个事件, 可以通过判断重叠结构来查看是哪一个socket
2. 将Socket、Accept、Recv、Send替换为WSASocket、AcceptEx、WSARecv、WSASend, 替换后的函数只负责投递相关的accept、recv、send操作, 当内部完成了这些操作后, 通过判断重叠结构中的事件来确认
大概流程:
while (1) { for 一个一个等待重叠结构中的事件 if (等待超时 || 有错误) // 具体处理 continue; 获取重叠结构上的结果 重置事件 分类处理, 并继续投递 }
事件通知
通过等待事件进行处理, 每次处理完之后需要我们自己投递, 每个线程处理64个事件, 很多的客户端就需要很多线程
完成例程
相比于事件通知, 增加了回调函数, 系统会创建线程调用回调函数, 回调函数中是对recv和send的处理
每个客户端都有一根线程, 线程太多
完成端口
是在重叠IO模型上的优化
https://blog.csdn.net/piggyxp/article/details/6922277
1. 它会把网络操作完成的通知,都放在一个队列里面,只需要从这个队列里面取就可以。
2. Accept和AcceptEx的区别:
(1)最关键的,是因为AcceptEx是在客户端连入之前,就把客户端的Socket建立好了,也就是说,AcceptEx是先建立的Socket,然后才发出的AcceptEx调用,也就是说,在进行客户端的通信之前,无论是否有客户端连入,Socket都是提前建立好了;而不需要像accept是在客户端连入了之后,再现场去花费时间建立Socket。
(2)相比accept只能阻塞方式建立一个连入的入口,对于大量的并发客户端来讲,入口实在是有点挤;而AcceptEx可以同时在完成端口上投递多个请求
(3)AcceptEx还有一个非常体贴的优点,就是在投递AcceptEx的时候,我们还可以顺便在AcceptEx的同时,收取客户端发来的第一组数据,这个是同时进行的,也就是说,在我们收到AcceptEx完成的通知的时候,我们就已经把这第一组数据接完毕了;但是这也意味着,如果客户端只是连入但是不发送数据的话,我们就不会收到这个AcceptEx完成的通知
3.