本帖最后由 GuestCode 于 2009-08-27 02:38:27 编辑

解决方案 »

  1.   

    支持,IOCP的核心是异步与重叠。Unix下没有IOCP,我们通过select加一个设计优秀的模型,同样可以实现一个高性能的Socket Server。建议想学习Socket Server的朋友,浏览一下httpd的源码,还有一个优秀的Socket Server框架ACE,也建议有兴趣的朋友学习一下。
      

  2.   

    请问:为啥unix系统的网络性能通常都比windows高很多?
      

  3.   

    不知所云。LZ真的懂IOCP值得怀疑
      

  4.   

    看一下MS的网络编程那本书就知道了,作者测试过各种模型,性能最好的就是完成端口,5万个连接完全成功。
    最差的就是异步socket,也就是CAyncSocket封装的模式,最多一千多个连接。“其它的也不差”,楼主你说的这句话是什么意思?在你看来,5万个连接和一千连接是差不多的?
      

  5.   

    Unix没有IOCP,但是FreeBSD有kqueue,Linux有epoll,原理都是相同的。就是不像select那样轮询端口,而是端口可以读写时,异步的通知进程。而kqueue和epoll又分为水平触发和边缘触发。边缘触发比较稳定,但是编写程序时比较复杂。
    并没有神话IOCP kqueue epoll的意思,这些东西不是SOCKET的标准,是各个OS对SOCKET的扩展而已。是服务器编写中的基础知识啊
      

  6.   


    我不懂IOCP的时候,我从来没有怀疑过IOCP。
      

  7.   


    IOCP是介于一定情况下,它有优越性。但某种情况下,其它的模型并不比它差多少!
      

  8.   

    http://www.134555.cn  →请自行输入查看 每天提前公开三只暴涨黑马股←
      

  9.   

    iocp适合大并发量,密集的小数据投递。其实为每个连接准备发送队列是很正常的事,因为投递数据时可能会因各种各样的原因失败,这时就需要缓存到队列中,稍后发出。每次才投递一个发送请求给IOCP,等该请求已决后才又出列一个再投递给IOCP。这个也没什么,因为服务器面对的成千上万个客户,发送机会对于每个客户是要平等的。试想如果有个客户有大量的数据需要发送,那么就会有大量的缓冲区被这个客户占有。这样对其它客户是不公平的。
      

  10.   

    楼主批判的是那些宣称为IOCP的代码实际上并不是真正的IOCP的代码,要么使用了阻塞socket,要么消息循环采用WaitForMultipleEvents而非IOCP的GetIoCompletionStatus。许多错误使用IOCP的例子都是以因为IOCP的一个奇怪特征:并发连接和io投递的操作行为与其他模型,包括epoll在内,都不一致。在epoll里,当一个用户到来的时候会触发消息,然后再调用accept去接受这个客户,并得到socket。就如同当一组数据到来时会触发消息,并调用recv去接受这组数据一样。在IOCP里,先来一个accept再说(IOCP使用AcceptEx),得到的socket还是无效的,等到一个用户到来时,触发消息,通知系统刚才那个socket现在有效了,可以使用了。当你要接收数据的时候,不管数据有没有到来,先recv一下,等到数据真正到来的时候,buffer里面才填充了有效的数据。IOCP的麻烦就在于:数据还没到来的时候,你就要预先操作等待结果。但是你怎么知道数据有多长呢?我要准备多大的buffer才行呢?而且当用户disconnect后,如果对应的socket没有任何操作悬挂在循环中,那么你是无法得到通知的,知道某个时候程序想起这个socket并进行一个操作后才会得知该客户已经断开了。
      

  11.   


    支持,我写个就是用这个模式。当有数千个连接的时候,每个投递一个Send操作,并发就已经很大
      

  12.   

    据我的理解和实际经验:IOCP构架里面,对于服务端口,总要有个AcceptEx操作挂在那里,接收到一个客户之后,要立刻再挂起一个AcceptEx,再安排一个线程去为这个客户socket服务。对于每个客户socket,每次recv成功之后要立刻挂起一个recv再安排数据处理,这样才能第一时间获取客户发送过来的信息,包括连接断开的信息。许多宣称自己IOCP构架的代码都按照select的思维习惯来,先用select或者异步来测试一下socket有无数据,再来recv,结果是IOCP循环仅仅提供异步的结果,还不如写个纯的异步select反倒更简单。IOCP不需要对socket进行测试,先把操作发出去,然后等待结果(成功 or 失败)。所以真正的IOCP的吞吐量是惊人的,绝对不比linux的epoll差。
      

  13.   


    把大数据切割成小数据是一定要的,但怎么逐一发送,一个接一个的WSASend的吗?如果发了一半出错了怎么办?还是不要保存到队列,等待系统通加,然后什么时候再发送。
      

  14.   


    这样效率太低了。每次都要收到成功确认的话,那一个ping值为100ms的网络,100ms才能发完一个数据包,发送一个小数据包占用网卡的时间最多也就几ms,大量的时间都在等待答复。TCP保证顺序的,如果中间失败了,就基本上可以关闭这个socket了,后面的数据基本上不会到达目标主机了。如果采用流式TCP,后面的数据就不会被发送了,直接返回失败。UDP有这个问题,不过基于UDP的应用层都应该自己有数据验证的机制,请求发送端重发没收到的数据包。TCP协议本身的优化也是这样的,不会老老实实等每一个包的应答后再去发下一个包,而是连续发N个包,收到第一个包的应答后再继续发后面的包,若某个应答中断了,说明网络出故障了,再重发对应包。
      

  15.   

    最终也没说明白IOCP是怎么被神化了!?!?!?
      

  16.   

    Windows核心编程里说IOCP是Windows中最重要也是最复杂的模型,还是有一定道理的。
      

  17.   

    我在实际的编程中使用过IOCP模型,性能确实不错。我用VS2005的Debug跑的程序性能也非常快。其实,LZ的意思估计是说每种模型都有应用的范围,根据实际的需要选择合理的通讯模型才是重要的。PS:
    使用IOCP编程的关键在于如何正确的划分网络读写以及和
    网络协议之间的处理顺序。确实编写起来有一定的难度,
    不过一旦这层通了之后,你会对网络编程有一个更新的认识。
      

  18.   

    EPOLL是半成品,IOCP是成品,底层机制一样,协议栈的状态检查不需要用户去查询,由作业系统来通知。
    其实这是任何守护性逻辑高性能的基础机制。但是EPOLL只是告诉你现在可以读和写,即协议栈的读写缓冲被初始化或重设(对于写,上次数据已经提交并写缓冲重设为空,对于读,栈议栈读缓冲已经开始接受数据。)
    但是写和读的过程还是由用户来控制,系统只是告诉你已经为你准备好了和网络驱动对接好的读写的通道。如果某个通道的读写很慢,我们其实自己可以控制,比如要读8K字节,但经过x秒只读到几个字节,这说明这个通道很差,我们可以将这个IO通道从EPOLL中分离出来把它投递到一个阻塞的socket中,而不影响整个EPOLL的性能。所以EPOLL虽然是半成品,但用户有更高的控制权。而对于IOCP,从名称就可以知道,系统不仅控制IO通道的状态,而且把读写操作都做完了才通知用户。对于读,系统已经把数据读好放在buffer中,其实相当于是RBF,对于写,已经是写出了n长度的字节,所以即使某个IO通道上的传输很慢,你也无法控制,因为当你收到通知时,系统已经是读好数据或写出数据。所以IOCP在用户的控制上没有灵活的空间。但是由系统来做毕竟比普通的二流以下的程序员自己来控制性能普遍来说要更好一些。在高性能服务器的开发中,采用一个非阻塞的IO模型配两三个阻塞的socket混合处理,是最合理的,因为在大量连接中总会有一些客户端传输很慢,对于非常慢的连接,EPOLL,IOCP还不如阻塞模型处理性能更好,即时读写速度是一样的,但阻塞模型简单,上下文切换和内存分配的开销比较少。所以把一些很慢的连接重新投递到阻塞的socket上而让EPOLL能有更多的机会去处理传输非常快的连接才是非阻塞的优势。相比来说,IOCP就不能这样做。
      

  19.   

    看一堆人, 講了這麼久, 講到天花龍鳳的, 請問
    什麼樣子的情況下, 該使用non-blocking mode, 什麼樣情況下使用blocking mode
    什麼樣的情況下使用IOCP/EPOLL?
    請舉出某種系統當例子.
      

  20.   

    回70楼:
    当你有这些疑问的时候,说明你还没有足够的经验来理解这些事,就象刚上大一时,第一次开始接触数据结构时,我们会想什么时候该用array,什么时候该用link。等你有了一些程序基本后你自己就明白如何合理使用它们。采用不同的模型,不是控制传输,而是“分拈”数据。
    简单说对于大量连接(连接数据大而数据量较小,不象下载这样长连接)的应用而言,从网卡上来的数据要分发到不同的端口(如果同一机器设置多个IP还要先分发到相应的IP)的每个连接上,和阻塞方式一样网络接收数据的能力(我们只说它接收用户的数据)是一样的,但是同样量的数据要分给10个人和分给10000个人,你说哪个工作量大?分给10000个人,这一万个IO通道要不断切换,那么不同的模型本质就是如何切换IO通道的问题。
      

  21.   

    回 72 樓:
    你這樣講, 我還真的是不知你在講什麼呢.
    重覆看了看, 你前面是指data 由 dispatching 到不同的port 的工作量的話,哪麼後面講10 個人到一萬人
    是指什麼鬼呢? 是說IOCP 不會為每一個connection 開啟一個port? 所以沒dispatching 的overhead?
      

  22.   

    顶、 
    http://www.xinkeor.cn/?11604-1.html
      

  23.   

    IOCP 又不是迷思的話
    問題是, 十年前就有solaris 上的以二戰空戰為背景的網游了, solaris 上也沒有IOCP
    或EPOLL, 別人是怎麼做的呢?
      

  24.   

    很赞同 axman 的理解
      

  25.   

    确实,才100个连接完全没必要用完成端口
    事实上,在300个连接以下,IOCP的优越性基本上体现不出来
    不是神化IOCP,只是在Windows下,要面向更多的连接,程序员们不得不采用IOCP,如果有其他更简单的编程方式,谁还会去使用这么一套最复杂的东西
      

  26.   


    有epoll 和 kqueue 
      

  27.   

    iocp很简单, 只是应用起来需要掌握的东西比较多, 比如什么 内存池啊, 队列啊, Half Sync/Half Async模式和Leader/Follower模式等等...
    总的来说, 都不很复杂. 说复杂的人都是初学者和一些喜欢吹牛的人.
      

  28.   

    我kao,这个kaofu iocp还真不是简单