应用场景说明:完成端口在面向现实应用的许多网络通信中应用很广泛,例如大型多人在线游戏,大型即时通信系统,网吧管理系统以及企业管理系统等具有大量并发用户请求的场合。
实现目标说明:通过完成端口模型构建一款服务器软件,能够接受多个客户端的同时访问,并且每个客户端都可以给服务器发送数据,服务器能接收到客户发来的数据并且统计并打印字节数,并且把打印的字节数发送给客户端。
关键功能就是完成端口模型的设计,完成端口内部提供了线程池的管理,可以避免反复创建线程的开销,同时可以根据CPU的个数灵活地决定线程个数,减少线程调度的次数,从而提高了程序的并行处理能力。
整个程序开始后,完成端口进行初始化工作线程启动,套接字初始化连接初始化,然后将套接字与完成端口相关联,异步接收数据,然后对于结果结果进行判断,如果错误需要处理错误然后结束;如果正确并且没有新的完成端口对象则借书;如果正确并且有新的完成端口对象则继续轮回到将套接字与完成端口相关联这一步,继续完成程序。
1、程序设计的流程图
- 判断系统中安装了多少个处理器,创建n个工作线程,n一般取当前计算机中处理器个数。工作线程的主要功能是检测完成端口的状态,如果有来自客户的数据,则接收数据,处理请求;
- 初始化Windows Sockets环境,初始化套接字;
- 创建完成端口对象,将待处理网络请求的套接字与完成端口对象关联;
- 异步接收数据,无论能否接收到数据,都会直接返回。
2、主要接口函数说明
1.完成端口对象创建函数:
HANDLE WINAPI CreateIoCompletionPort(
_in HANDLE FileHandle,
_in HANDLE ExistingCompletionPort,
_in ULONG_PTR CompletionKey,
_in DWOR NumberOfConcurrentThreads
);
FileHandle:是重叠I/O操作关联的文件句柄。
ExistingCompletionPort:是已经存在的完成端口句柄。
CompletionKey:包含在每个I/O完成数据包中用于指定文件句柄的单句柄数据,它将与FileHandle文件句柄关联在一起,应用程序可以再此存储任意类型的信息,通常是一个指针。
NumberOfConcurrentThreads:指定I/O完成端口上操作系统允许的并发处理I/O完成数据包的最大线程数量。
返回值含义:若函数执行成功,返回与套接字句柄相关联的I/O完成端口句柄;若函数执行失败,返回NULL。
2.等待重叠I/O操作结果函数:
BOOL WINAPI GetQueuedCompletionStatus(
_in HANDLE CompletionPort,
_out LPDWORD lpNumberOfBytes,
_out PULONG_PTR lpCompletionKey,
_out LPOVERLANPPED* lpOverlapped,
_in DWORD dwMilliseconds
)
CompletionPort:完成端口句柄。
lpNumberOfBytes:获取已经完成的I/O操作中传输的字节数
lpCompletionKey:或区域已经完成的I/O操作的文件句柄相关联的点句柄数据,在一个套接字首次与完成端口关联到一起的时候,那些数据便于一个特定的逃跑将诶自己并对应起来了,这些数据是运行CreateIoCompletionPort()函数时通过 CompletionKey参数传递的。
lpOverlapped:在完成的I/O操作开始时指定的重叠结构地址,在它后面跟对单I/O操作数据。
dwMilliseconds:函数在完成端口上等待的时间。
返回值含义:若函数从完成端口上获取到成功的I/O操作完成通知包,返回非0值;若函数从完成端口上获取到失败的I/O操作完成通知包或是函数调用超时,返回0值。
3.数据接收函数,覆盖了标准的recv函数,用于客户端对于服务器的数据发送功能。
WSARecv(
_in SOCKET s,
_inout LPWSABUF lpBuffers,
_in WDORD dwBufferCount,
_out LPDWORD lpNumberOfBytesRecvd,
_inout LPDWORD lpFlags,
_in LPWSAOVERLAPPED lpOverlapped,
_in LP