ECHO服务器代码中对于PerIOData和PerHandleData数据都采用了GlobalAlloc,并没有采用数组进行统一管理,而且还只开了一个线程,也就是说没有socket池和线程池。
在线程函数中处理完成操作的io数据,可以通过CompletionKey获取PerHanleData,可以通过Overlapped结构间接的获取PerIOData,因此可以对不同的socket进行操作,无需统一管理。这样好像就已经完成了IOCP的搭建,那么为什么真正应用上的IOCP并不像ECHO这么简单呢?要维护socket池和线程池的目的在于什么呢?

解决方案 »

  1.   

    而且ECHO服务器在处理一个端口完成的时候,用的是发送的和接受的字节数相比较的方法,判断下一次的IO操作。实际过程中如果是一次发送数百KB的数据,不是接受再原版返回的话,该怎么写这个处理代码?
      

  2.   

    http://community.csdn.net/Expert/topic/3056/3056877.xml?temp=.8440058
      

  3.   

    1。这样好像就已经完成了IOCP的搭建,那么为什么真正应用上的IOCP并不像ECHO这么简单呢?
      真正的IOCP程序有他自己的数据流格式和自己的业务逻辑,这个ECHO是没有的,关这就简单好多。有了数据流格式,那么在接收的时候就要判断收到的是否是一个完整的数据包,如果不是就要继续接收。在接收完一个完整的数据包后,通常要对包进行解析并处理其请求,而且通常解包与请求处理都是在另外的线程中完成的,并不是在完成端口的I/O线程中完成。所以真的要实现一个完成业务的IOCP SERVER还是有很多事情要做的。
    2.要维护socket池和线程池的目的在于什么呢?
     我估计你说SOCKET池是单句饼结构对象,我习惯叫它为SessionContext.通常为每一个连接的CLIENT分配一个这样的SessionContext。维护这样一个Context池主要还是为了提高效率,避免频繁的new或者在堆上分配内存。(在堆上分配内存相对来讲比较耗费时间)另外还有就是避免频繁的分配造成内存碎片的产生(具体为什么会产生碎片请见WIN32内存详细文档)。至于线程池那就更加需要了。在一个服务器内,通常存在多种线程,(完成I/O线程,数据解析线程,业务处理线程等)而且某种线程还存在多个,为了更好管理这些线程,是有必要进行封装的。而且有的服务器还实现了更智能的功能,就是自动根据服务器繁忙程度自动调节线程数量。
    3.实际过程中如果是一次发送数百KB的数据,不是接受再原版返回的话,该怎么写这个处理代码?
      这个看服务器具体业务处理流程怎么走了,我通常是将读取,发送,业务处理3者分开,完成I/O线程中读取操作是永远循环的,而发送操作则是由业务处理来决定是否发送,所以通常是这个流程: 读=》处理=》发送。另外如果考虑到读/写可能同时进行,那么你所看的 那个示例中的代码可能就有问题了,因为它是用的同一个OVERLAPPED (同一个单句柄),这样读写事件完成后有时候会无法区分,所以通常应该是为读写分别设立一个OVERLAPPED.一个好的服务器模型是很复杂的,有时候并不是采用了完成端口就能够万事大吉,还需要考虑的事情还有好多,很多问题我也希望象高手们学习!!
      

  4.   

    我正在ECHO的基础上改写一个新的IOCP,想实现猜数字的功能。现在客户端第一次猜数字的时候,服务器正常工作,有两次完成端口的返回——一次是收到了客户端猜的数字,一次是服务器成功的把判断信息(Right/Wrong)发送给客户端。但是客户端在此发送猜测的数字,服务器的GetQueuedCompletionStatus一直阻塞不返回,这是为什么阿?