IOCP

10 views
Skip to first unread message

fhq...@hotmail.com

unread,
Jan 9, 2007, 8:50:19 PM1/9/07
to 网络通信架构&技术
网上有许多介绍IOCP(Input/Output Completion
Port)技术的文章,但是TMD在真正做项目的时候大多用不上。把《Windows网络编程第二版》快翻烂了才终于弄明白了这项技术。

我的的目标是:


1、使用IPV4技术构建一个支持65000个并发连接的代理服务器

2、能够在网络上传输大型文件

3、写出助手类TIOCPNet

对关键字的一些描述:

1、IOCP:

IOCP以内核模式发现Socket事件,并且IOCP提供了立即连接用户数据和Socket对象的机制。

2、AcceptEx:

在超过30,000个并发连接连接到服务器的时候,使用Accept或WSAAccept将会得到WSAENOBUFS(10055)错误。出现这个错误的原因是因为系统无法准备好资源来捕捉这么多并发连接所发送过来的数据。因此,必须在使用Socket资源前准备好这些Socket资源,这就只能使用AcceptEx了。使用AcceptEx的主要优势是:在使用Socket之前就将Socket准备好了。不过AcceptEx使用起来相当繁琐,而且非常麻烦。

3、Static Memory:
用户在服务器端使用(Per-Allocated
Memory)。当接收到一个发送过来的数据报后,必须使用静态内存。在TIOCPNet中将使用类TPerllocator来获取Per-Allocated
Memory。

4、Sliced Data Chunk:

曾经遇到过这种情况:即在使用WriteFile、WSASend或Send函数发送超过1KB字节的数据包时接受端无法正确接收数据。造成这个问题的原因应该是发送的数据报的大小超过了网络设备(路由器、HUB等)的MUT(Most
Transfer
Unit)的最小值。网络设备MUT的最小值为576字节。因此应该将一个大的数据包拆分为比576字节小的数据包,在TIOCPNet中,我定义数据单元块的大小(BUFFER_UNIT_SIZE)为512字节。

5、线程Thread:

如果服务器逻辑中需要进行一些I/O操作的话,最好构建一些线程,但是线程的数量也不是越多越好的。这是因为线程的调度和上下文切换也都是需要耗费CPU资源的,在一个系统中有超过10000个的线程并发运行时,CPU估计就要挂了,在TIOCPNet中我为每个CPU分配了两个线程。

TIOCPNET是实现上述想法的具体实现类。TIOCPNet的操作步骤如下:


1、TIOCPet将自行准备那些诸如Per-Allocated内存块、完成端口、其他句柄等资源;

2、TIOCPNet将创建监听Socket对象

3、TIOCPNet生成Pre-Generates
Sockets和它自己的缓冲Socket,并将他们放置到AcceptEx的AccepTable中。

4、接受用户发出的连接请求。


5、当一个Socket对象读取数据包时,TIOCPNet对象将把他们放置到他们自己的Pre-Allocated
Reading Slots中,并向服务器发送一个事件。


6、当服务器写数据包时,TIOCPNet将这些数据放置到Pre-Allocated
Writing
Blocks中并调用PostQueuedCompletionStatus函数,然后使用工作器线程发送这些数据包


7、当客户端用户关闭连接时,TIOCPNet关闭相应Socket对象,但是TIOCPNet并不会真正释放内存缓冲区,紧紧再分配这些缓冲区。

Reply all
Reply to author
Forward
0 new messages