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. 

 

版权声明:本文为xkDiogt原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xkDiogt/p/13514287.html