据我的理解和实际经验:IOCP构架里面,对于服务端口,总要有个AcceptEx操作挂在那里,接收到一个客户之后,要立刻再挂起一个AcceptEx,再安排一个线程去为这个客户socket服务。对于每个客户socket,每次recv成功之后要立刻挂起一个recv再安排数据处理,这样才能第一时间获取客户发送过来的信息,包括连接断开的信息。许多宣称自己IOCP构架的代码都按照select的思维习惯来,先用select或者异步来测试一下socket有无数据,再来recv,结果是IOCP循环仅仅提供异步的结果,还不如写个纯的异步select反倒更简单。IOCP不需要对socket进行测试,先把操作发出去,然后等待结果(成功 or 失败)。所以真正的IOCP的吞吐量是惊人的,绝对不比linux的epoll差。
最差的就是异步socket,也就是CAyncSocket封装的模式,最多一千多个连接。“其它的也不差”,楼主你说的这句话是什么意思?在你看来,5万个连接和一千连接是差不多的?
并没有神话IOCP kqueue epoll的意思,这些东西不是SOCKET的标准,是各个OS对SOCKET的扩展而已。是服务器编写中的基础知识啊
我不懂IOCP的时候,我从来没有怀疑过IOCP。
IOCP是介于一定情况下,它有优越性。但某种情况下,其它的模型并不比它差多少!
支持,我写个就是用这个模式。当有数千个连接的时候,每个投递一个Send操作,并发就已经很大
把大数据切割成小数据是一定要的,但怎么逐一发送,一个接一个的WSASend的吗?如果发了一半出错了怎么办?还是不要保存到队列,等待系统通加,然后什么时候再发送。
这样效率太低了。每次都要收到成功确认的话,那一个ping值为100ms的网络,100ms才能发完一个数据包,发送一个小数据包占用网卡的时间最多也就几ms,大量的时间都在等待答复。TCP保证顺序的,如果中间失败了,就基本上可以关闭这个socket了,后面的数据基本上不会到达目标主机了。如果采用流式TCP,后面的数据就不会被发送了,直接返回失败。UDP有这个问题,不过基于UDP的应用层都应该自己有数据验证的机制,请求发送端重发没收到的数据包。TCP协议本身的优化也是这样的,不会老老实实等每一个包的应答后再去发下一个包,而是连续发N个包,收到第一个包的应答后再继续发后面的包,若某个应答中断了,说明网络出故障了,再重发对应包。
使用IOCP编程的关键在于如何正确的划分网络读写以及和
网络协议之间的处理顺序。确实编写起来有一定的难度,
不过一旦这层通了之后,你会对网络编程有一个更新的认识。
其实这是任何守护性逻辑高性能的基础机制。但是EPOLL只是告诉你现在可以读和写,即协议栈的读写缓冲被初始化或重设(对于写,上次数据已经提交并写缓冲重设为空,对于读,栈议栈读缓冲已经开始接受数据。)
但是写和读的过程还是由用户来控制,系统只是告诉你已经为你准备好了和网络驱动对接好的读写的通道。如果某个通道的读写很慢,我们其实自己可以控制,比如要读8K字节,但经过x秒只读到几个字节,这说明这个通道很差,我们可以将这个IO通道从EPOLL中分离出来把它投递到一个阻塞的socket中,而不影响整个EPOLL的性能。所以EPOLL虽然是半成品,但用户有更高的控制权。而对于IOCP,从名称就可以知道,系统不仅控制IO通道的状态,而且把读写操作都做完了才通知用户。对于读,系统已经把数据读好放在buffer中,其实相当于是RBF,对于写,已经是写出了n长度的字节,所以即使某个IO通道上的传输很慢,你也无法控制,因为当你收到通知时,系统已经是读好数据或写出数据。所以IOCP在用户的控制上没有灵活的空间。但是由系统来做毕竟比普通的二流以下的程序员自己来控制性能普遍来说要更好一些。在高性能服务器的开发中,采用一个非阻塞的IO模型配两三个阻塞的socket混合处理,是最合理的,因为在大量连接中总会有一些客户端传输很慢,对于非常慢的连接,EPOLL,IOCP还不如阻塞模型处理性能更好,即时读写速度是一样的,但阻塞模型简单,上下文切换和内存分配的开销比较少。所以把一些很慢的连接重新投递到阻塞的socket上而让EPOLL能有更多的机会去处理传输非常快的连接才是非阻塞的优势。相比来说,IOCP就不能这样做。
什麼樣子的情況下, 該使用non-blocking mode, 什麼樣情況下使用blocking mode
什麼樣的情況下使用IOCP/EPOLL?
請舉出某種系統當例子.
当你有这些疑问的时候,说明你还没有足够的经验来理解这些事,就象刚上大一时,第一次开始接触数据结构时,我们会想什么时候该用array,什么时候该用link。等你有了一些程序基本后你自己就明白如何合理使用它们。采用不同的模型,不是控制传输,而是“分拈”数据。
简单说对于大量连接(连接数据大而数据量较小,不象下载这样长连接)的应用而言,从网卡上来的数据要分发到不同的端口(如果同一机器设置多个IP还要先分发到相应的IP)的每个连接上,和阻塞方式一样网络接收数据的能力(我们只说它接收用户的数据)是一样的,但是同样量的数据要分给10个人和分给10000个人,你说哪个工作量大?分给10000个人,这一万个IO通道要不断切换,那么不同的模型本质就是如何切换IO通道的问题。
你這樣講, 我還真的是不知你在講什麼呢.
重覆看了看, 你前面是指data 由 dispatching 到不同的port 的工作量的話,哪麼後面講10 個人到一萬人
是指什麼鬼呢? 是說IOCP 不會為每一個connection 開啟一個port? 所以沒dispatching 的overhead?
http://www.xinkeor.cn/?11604-1.html
問題是, 十年前就有solaris 上的以二戰空戰為背景的網游了, solaris 上也沒有IOCP
或EPOLL, 別人是怎麼做的呢?
事实上,在300个连接以下,IOCP的优越性基本上体现不出来
不是神化IOCP,只是在Windows下,要面向更多的连接,程序员们不得不采用IOCP,如果有其他更简单的编程方式,谁还会去使用这么一套最复杂的东西
有epoll 和 kqueue
总的来说, 都不很复杂. 说复杂的人都是初学者和一些喜欢吹牛的人.