Winsock重叠模型
来源:互联网 发布:vscode搭建本地服务器 编辑:程序博客网 时间:2024/05/17 01:59
重叠模型的基本设计原理是让应用程序使用一个重叠的数据结构,一次投递一个或多个Winsock I/O请求。针对那些提交的请求,在它们完成之后,应用程序为他们提供服务。
要想在一个套接字上使用重叠I/O模型,首先必须使用WSA_FLAG_OVERLAPPED这个标志,创建一个套接字。如下所示:
s=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
创建套接字的时候,假如使用的是socket函数,而非WSASocket函数,那么会默认设置WSA_FLAG_OVERLAPPED标志。成功创建好一个套接字,同时将其与一个本地接口绑定在一起后,便可以开始进行重叠I/O操作,方法是调用下属的Winsock函数,同时指定一个WSAOVERLAPPED结构(可选):
- WSASend
- WSASendTo
- WSARecv
- WSARecvFrom
- WSAIoctl
- AcceptEx
- TransmitFile
以上的每个函数都与一个套接字上的数据的发送、数据接收以及连接的接收有关。因此这些活动可能会花费极少的时间才能完成。这正是每个函数都可接收一个WSAOVERLAPPED结构作为参数的原因。若随一个WSAOVERLAPPED结构一起调用这些函数,函数会立即完成并返回,无论套接字是否设定为锁定模式。它们依赖于WSAOVERLAPPED结构来返回一个I/O请求的返回。主要有两个方法可用来管理一个重叠I/O请求的完成:我们的应用程序可以等待”事件对象通知“,亦可通过”完成例程“,对已经完成的请求加以处理。上面列出的函数(AcceptEx除外)还有另一个常用参数:lpCompletionROUTINE。该参数指定的是一个可选的指针,指向一个完成例程函数。在重叠请求完成后调用。
1.事件对象同时
重叠I/O的事件通知方法要求将Win32的事件对象与WSAOVERLAPPED结构关联在一起,若使用一个WSAOVERLAPPED结构,发出像WSASend和WSARecv这样的I/O调用,他们会立即返回。
通常大家会发现I/O调用会以失败告终,返回SOCKET_ERROR。使用WSAGetLastError函数,便可获得与错误状态有关的一个报告,这个错误状态意味着I/O操作正在进行。稍后的某个时间我们的应用程序需要等候与WSAOVERLAPPED结构对应的事件对象,了解一个重叠I/O请示何时完成。WSAOVERLAPPED结构在一个重叠I/O请求的初始化,及后续完成之间,提供了一种沟通或通讯机制。
要将一个WSAOVERLAPPED结构与一个事件对象联系起来,可以用WSACreateEvent函数来创建一个事件对象句柄。一旦创建好一个事件对象句柄,简单地将重叠结构的hEvent字段分配给事件句柄,再使用重叠结构,调用一个Winsock函数即可,比如WSASend或WSARecv。
一个重叠I/O请求最终完成后,我们的应用程序要负责取回重叠I/O操作的结果。一个重叠请求操作最终完成之后,在事件通知方法中,Winsock会更改与一个WSAOVERLAPPED结构对应的一个事件对象的事件传信状态,将其从”未传信“变为”已传信“。由于一个事件对象已分配给WSAOVERLAPPED结构,所以只需简单地调用WSAWaitForMultipleEvents函数,从而判断出一个重叠I/O请求在什么时候完成。此处需要注意的是WSAWaitForMultipleEvents函数一次最多只能等待64个事件对象。发现一次重叠请求完成后,接着需要调用WSAGetIoverlappedResult(取得重叠结构)函数,判断哪个重叠调用到底是成功还是失败。该函数的定义如下:
BOOL WSAGetOverlappedResult(
Socket s,
LPWSAOVERLAPPED lpOverlapped,
LPWORD lpcbTransfer,
BOOL fWait,
LPWORD lpdwFlags
);
其中:
Socket s:指定在重叠操作开始的时候,与之对应的那个套接字。
LPWSAOVERLAPPED lpOverlapped:是一个指针,对应于在重叠操作开始时指定的那个WSAOVERLAPPED结构。
LPWORD lpcbTransfer:参数是一个指针对应一个DWORD变量指定发送或接收的实际字节数。
由此我们总结Winsock重叠模型的编程步骤如下:
- 创建一个套接字,开始在指定的端口上监听连接请求
- 接收一个进入连接的请求
- 为接收的套接字新建一个WSAOVERLAPPED结构,并为该结构分配一个事件对象句柄。也将事件对象句柄分配给一个事件数组,以便稍后由WSAWaitForMultipleEvents函数使用。
- 在套接字上投递一个异步的WSARecv请求,指定参数为WSAOVERLAPPED机构。(注意 函数通常会以失败告终,返回SOCKET_ERROR错误状态WSA_IO_PENDING,即I/O操作尚未完成)。
- 使用步骤3的事件数组调用WSAWaitForMultipleEvents函数,并等待与重叠调用关联在一起的事件进入“已传信”状态(换言之,等待那个事件“触发”)。
- WSAWaitForMultipleEvents函数完成后,针对事件数组,调用WSAResetEvent(重设事件)函数,从而重设事件对象,并对完成的重叠请求进行处理。
- 使用WSAGetOverlappedResult函数,判断重叠调用返回状态是什么。
- 在套接字上投递另一个WSARecv请求。
- 重复步骤5-8。
- winsock重叠IO模型
- Winsock重叠模型
- WinSock IO模型---重叠模型
- WinSock重叠I/O模型
- WinSock重叠IO模型一
- winsock重叠iI/O模型
- winsock重叠iI/O模型
- winsock重叠iI/O模型
- winsock重叠iI/O模型
- WinSock重叠I/O模型
- WinSock重叠I/O模型
- WinSock 重叠I/O模型
- WinSock重叠I/O模型
- WinSock重叠I/O模型
- WinSock重叠I/O模型
- WinSock重叠I/O模型
- winsock IO模型 重叠端口
- WinSock重叠I/O模型
- hdu 1247 (字典树)
- CString 类相应函数
- 植物大战僵尸中文版修改器源码
- 黑马程序员——C#复习之图片查看器
- Programmer & Love
- Winsock重叠模型
- Smith Numbers
- NSIS脚本编译后乱码
- oracle用户管理
- Hdu 1561 The more, The Better
- 放大的X
- 一步一步搭建Grails项目环境
- 中国阳历农历的转换
- 对搜索的文档进行排序