⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 6-5.html

📁 介绍各种平台进行SOCKET编程的好东东。
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb_2312-80">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<TITLE>6</TITLE>
</HEAD>
<BODY>

<B><FONT FACE="黑体" LANG="ZH-CN" SIZE=5><P><A NAME="_Toc336626888"><A NAME="_Toc336792971"><A NAME="_Toc336793447"></FONT><FONT FACE="Arial" SIZE=5>6.5 </FONT><FONT FACE="黑体" LANG="ZH-CN" SIZE=5>重叠</FONT><FONT FACE="Arial" SIZE=5>I/O</FONT><FONT FACE="黑体" LANG="ZH-CN" SIZE=5>和事件对象</A></A></A></P>
</B></FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">&#9;</FONT><FONT SIZE=3>Windows Sockets 2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>引入了重叠</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>的概念并且要求所有的传输协议提供者都支持这一功能。重叠</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>仅能在由</FONT><FONT SIZE=3>WSASocket()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数打开的套接口上使用(使用</FONT><FONT SIZE=3>WSA_FLAG_OVERLAPPED</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>标记)。这种方式的使用将采用</FONT><FONT SIZE=3>Win32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>建立的模型。</P>
<P ALIGN="JUSTIFY">&#9;对于接收,应用程序使用</FONT><FONT SIZE=3>WSARecv()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数或</FONT><FONT SIZE=3>WSARecvFrom()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数来提供存放接收数据的缓冲区。如果数据在网络接收以前,应用程序已经提供了一个或多个数据缓冲区,那么接收的数据就可以立即被存放进用户缓冲区。这样可以省去使用</FONT><FONT SIZE=3>recv()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数和</FONT><FONT SIZE=3>recvfrom()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数时需要进行的拷贝工作。如果在应用程序提供数据缓冲区时已经有数据到来,那么接收的数据将被立即拷贝进用户缓冲区。如果数据到来时,应用程序没有提供接收缓冲区,那么网络将回到我们熟悉的同步操作方式-传送来的数据将被存放进内部缓冲区,直到应用程序发出了接收调用并且提供了接收缓冲区,这时接收的数据就被拷贝进接收缓冲区。这种做法会有一个例外:就是当应用程序使用</FONT><FONT SIZE=3>setsockopt()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数把接收缓冲区长度置为了</FONT><FONT SIZE=3>0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。在这种情况下,对于可靠传输协议,只有在应用程序提供了接收数据缓冲区后,数据才会被接收;而对于不可靠传输协议,数据将会丢失。</P>
<P ALIGN="JUSTIFY">&#9;对于发送的一方,应用程序使用</FONT><FONT SIZE=3>WSASend()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数或</FONT><FONT SIZE=3>WSASendTo()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数提供一个指向已填充的数据缓冲区的指针。应用程序不应在网络使用完该缓冲区的数据以前以任何方式破坏该缓冲区的数据。</P>
<P ALIGN="JUSTIFY">&#9;重叠发送和接收调用会立即返回。如果返回值是</FONT><FONT SIZE=3>0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,那么表明了</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>操作已经完成,对应的完成指示也已经可以得到。如果返回值是</FONT><FONT SIZE=3>SOCKET_ERROR</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,并且错误代码是</FONT><FONT SIZE=3>WSA_IO_PENDING</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,那么表明重叠操作已经被成功地初始化,今后发送缓冲区被用完或者接收缓冲区被填满时,将会有完成指示。任何其他的错误代码表明了初始化没有成功,今后也不会有什么完成指示。</P>
<P ALIGN="JUSTIFY">&#9;发送操作和接收操作都可以被重叠使用。接收函数可以被多次调用,发出接收缓冲区,准备接收到来的数据。发送函数也可以被多次调用,组成一个发送缓冲区队列。要注意的是,应用程序可以通过按顺序提供发送缓冲区来确保一系列重叠发送操作的顺序,但是对应的完成指示有可能是按照另外的顺序排列的。同样的,在接收数据的一方,缓冲区是按照被提供的顺序填充的,但是完成指示也可能按照另外的顺序排列。</P>
<P ALIGN="JUSTIFY">&#9;</FONT><FONT SIZE=3>WSAIoctl()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数(</FONT><FONT SIZE=3>ioctolsocket()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数的增强版本)还可以使用重叠</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>操作的延迟完成特性。</P>
<P ALIGN="JUSTIFY"> </P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=5><P><A NAME="_Toc336626889"><A NAME="_Toc336792972"><A NAME="_Toc336793448"></FONT><FONT SIZE=5>6.5.1 </FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=5>事件对象</A></A></A></P>
</B></FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">&#9;重叠</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>概念的引入需要建立一个机制使得应用程序能够正确的把发送和接收事件与今后它们完成时的指示相连接。在</FONT><FONT SIZE=3>Windows Sockets 2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中,这一点是通过事件对象实现的,它采用了</FONT><FONT SIZE=3>Win32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>事件的模型。</FONT><FONT SIZE=3>Windows Sockets</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>事件对象是一个相当简单的结构,它可以被创建,关闭,设置,清除,等待和检查。它们的主要用处是使得应用程序能够阻塞并等待直到一个或多个事件对象被设置。</P>
<P ALIGN="JUSTIFY">&#9;应用程序可以使用</FONT><FONT SIZE=3>WSACreateEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数来得到一个事件对象句柄,这个句柄可以作为以后的重叠发送和接收函数的输入参数(</FONT><FONT SIZE=3>WSASend()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSASendTo()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSARecv()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSARecvFrom()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>)。事件对象在创建时被清除,在相关的重叠</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>操作完成时由传输协议提供者设置(或者成功,或者出错)。每个被</FONT><FONT SIZE=3>WSACreateEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数创建的事件对象都必须有对应的</FONT><FONT SIZE=3>WSACloseEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数释放它。</P>
<P ALIGN="JUSTIFY">&#9;</FONT><FONT SIZE=3>WSAEventSelect()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数把一个或多个</FONT><FONT SIZE=3>FD_XXX</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>网络事件与一个事件对象连接。这将在</FONT><FONT SIZE=3>2.6</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中讨论。</P>
<P ALIGN="JUSTIFY">&#9;在</FONT><FONT SIZE=3>32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>位环境中,与事件对象相关的函数,包括</FONT><FONT SIZE=3>WSACreateEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSACloseEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSASetEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSAResetEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>WSAWaitForMultipleEvent()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>和</FONT><FONT SIZE=3>WSAGetOverlappedResult()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,都被直接映射到对应的</FONT><FONT SIZE=3>Win32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数,例如没有</FONT><FONT SIZE=3>WSA</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>前缀的同名函数。</P>
<P ALIGN="JUSTIFY"> </P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=5><P><A NAME="_Toc336626890"><A NAME="_Toc336792973"><A NAME="_Toc336793449"></FONT><FONT SIZE=5>6.5.2 </FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=5>接收操作完成指示</A></A></A></P>
</B></FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">&#9;为了提供给应用程序适当的灵活性,</FONT><FONT SIZE=3>Windows Sockets 2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>为接收操作完成指示提供了多个选项。它们包括:等待(阻塞)事件对象,检查事件对象和套接口</FONT><FONT SIZE=3>I/O</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>完成例程。</P>
<P ALIGN="JUSTIFY"> </P>
</FONT><B><FONT FACE="黑体" LANG="ZH-CN" SIZE=4><P><A NAME="_Toc336792974"><A NAME="_Toc336793450"></FONT><FONT FACE="Arial" SIZE=4>6.5.2.1 </FONT><FONT FACE="黑体" LANG="ZH-CN" SIZE=4>阻塞并且等待完成指示。</A></A></P>
</B></FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">&#9;应用程序可以使用</FONT><FONT SIZE=3>WSAWaitForMultipleEvents()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数来选择阻塞程序直到一个或多个事件对象被设置。在</FONT><FONT SIZE=3>Win16</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>实现中,这种方式将使用一个阻塞钩子,就象在标准的阻塞套接口操作时一样。在</FONT><FONT SIZE=3>Win32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>实现中,进程或线程会被真正地阻塞。因为</FONT><FONT SIZE=3>Windows Sockets 2</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>事件对象被实现成</FONT><FONT SIZE=3>Win32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>事件,所以</FONT><FONT SIZE=3>Win32</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数</FONT><FONT SIZE=3>WaitForMultipleObjects()</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>也可以使用。这在线程需要阻塞套接口和非套接口事件时将会非常有用处。</P>
<P ALIGN="JUSTIFY"> </P>
</FONT><B><FONT FACE="黑体" LANG="ZH-CN" SIZE=4><P><A NAME="_Toc336792975"><A NAME="_Toc336793451"></FONT><FONT FACE="Arial" SIZE=4>6.5.2.2 </FONT><FONT FACE="黑体" LANG="ZH-CN" SIZE=4>检查完成指示</A></A></P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -