2014年8月

完成端口是真正意义上的异步模型,如果硬要程序需要同时与成百上千个客户端同时通信,使用完成端口模型可以大大提高应用程序的性能,提升并发处理能力。完成端口会充分利用Windows内核来进行I/O的调度,是用于C/S通信模式中性能最好的网络通信模型,没有之一;甚至连和它性能接近的通信模型都没有。

1、创建完成端口
调用CreateIoCompletionPort()函数创建一个完成端口,而且在一般情况下,我们需要且只需要建立这一个完成端口,把它的句柄保存好,我们今后会经常用到它。

HANDLE CreateIoCompletionPort(
    HANDLE FileHandle,
    HANDLE ExistingCompletionPort,
    ULONG_PTR CompletionKey,
    DWORD NumberOfConcurrentThreads
);

CreateIoCompletionPort可以将一个I/O完成端口(IOCP)关联到一个或多个文件句柄(Socket),或与文件句柄无关的I/O完成端口。将Socket与完成端口关联后,应用程序就可以接收到该Socket上执行异步I/O操作完成后发送的通知。

- 阅读剩余部分 -

重叠I/O是Win32文件操作的一项技术,使用它可以在一个重叠结构上提交多个I/O请求,并在数据传输结束后通知应用程序,系统通知应用程序的形式有两种,事件通知和完成例程。

1、常用函数
(1)WSASocket函数

SOCKET WSASocket(int af,int type,int protocol,LPWSAPROTOCOL_INFO lpProtocolInfo,GROUP g,DWORD dwFlags)

af:地址家族,通常用AF_INET
type:新建Socket类型,SOCK_STREAM基于流的Socket,SOCK_DGRAM基于数据报的Socket;
protocol:Socket使用的协议;
lpProtocolInfo:新建Socket特性,一般NULL
g:预留字段,一般为0;
dwFlags:指定Socket属性的标识,在重叠I/O模型中,dwFlags需要设置为WSA_FLAG_OVERLAPPED
重叠Socket可以使用WSASend、WSASendTo、WSARecv、WARecvFrom和WSAIoctl等函数执行重叠I/O操作,即同时初始化和处理多个操作。

- 阅读剩余部分 -

WSAEventSelect模型是另外一个异步I/O模型,它与WSAAsyncSelect的最大区别是网络事件发生时系统通知应用程序的方式不同,WSAAsyncSelect以消息形式通知应用程序,而WSAEventSelect以事件形式进行通知。

1、WSAEventSelect()函数
WSAEventSelect函数可以为Socket注册网络事件,并将指定的事件关联到指定的网络事件集合。

int WSAEventSelect(Socket s,WSAEVENT hEventObject,long lNetworkEvents);

s:Socket;
hEventObject:与网络事件集合相关联的事件句柄;
lNetworkEvents:感兴趣的网络事件集合;
WSAEventSelect函数设置相关的事件对象,并在网络事件内部记录中保存时间的发生。
应用程序调用WSAWaitForMultipleEvens函数等待事件的发生,调用WSAEnumNetwordEvents函数获取内部网络事件记录的内容,决定发生了哪个被提名的网络事件。

- 阅读剩余部分 -

在WSAAsyncSelect模型中,应用程序可以在一个Socket上接收以Windows消息为基础的网络事件通知,它实现了读写数据的异步通知功能,但不提供异步的数据传送。

1、WSAAsyncSelect()函数
WSAAsyncSelect模型的核心是WSAAsyncSelect()函数,它可以使Windows程序接收网络事件消息。

int WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent);

s:事件通知所需要的Socket;
hWnd:网络事件发生时接受消息的窗口句柄;
wMsg:网络事件发生时接收的消息;
lEvent:感兴趣的网络事件;
同时函数调用时自动将Socket s设置为非阻塞模式。

- 阅读剩余部分 -

在Select模型中,可以使Windows Sockets应用程序同时对多个Socket进行管理,调用select()函数可以获取指定Socket的状态。

1、Select()函数
Select()函数可以决定一组Socket的状态,通常操作于就绪的Socket。使用fd_set结构体来管理多个Socket。

typedef struct fd_set{
    u_int fd_count;
    SOCKET fd_arrat[FD_SETSIZE];
}fd_set;

参数fd_count表示集合中包含的Socket数目,fd_array是保存Socket的数组。

- 阅读剩余部分 -