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

📄 io-strategies.html

📁 SDK FAQ集
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"><html lang="en"><head><title>Winsock Programmer's FAQ: Articles</title><link rel="Stylesheet" type="text/css" href="../faq.css"></head><body bgcolor="#ffffee" text="#000000" link="#491e00" vlink="#7d2e01" alink="#da7417"><!--  ---- Header Bar ----  --><table border="0" width="95%" bgcolor="#006000" cellpadding="5" cellspacing="3" align="center">	<tr>		<td align="left" bgcolor="#e0e0c0">			<font size="2" face=Verdana,Arial,Helvetica>				<b><a href="../articles/impatient.html">&lt;&lt;</a></b>			</font>		</td>		<td align="center">			<font face=Verdana,Arial,Helvetica color="#ffffee">				<p align=center class=bigger3><b>				Winsock Programmer's FAQ<br>				Section 7: Articles<br>				</b></p>			</font>			</td>		<td align="right" bgcolor="#e0e0c0">			<font size="2" face=Verdana,Arial,Helvetica>				<b><a href="../articles/effective-tcp.html">&gt;&gt;</a></b>			</font>		</td>	</tr></table><!--  ---- Body Table ----  --><table width="95%" border="0" cellpadding="10">	<tr valign="top">		<td><H3>Which I/O Strategy Should I Use?</H3><p><I>by Warren Young</I></p><P>There are several different conventions for communicating with Winsock,and each method has distinct advantages. The question of the hour is,what are these advantages, and how does someone choose the conventionthat makes the most sense for their application? The choices are:</p><UL><LI><B><A HREF="../glossary.html#blocking">Blocking</A> sockets</B> -By default, a Winsock call blocks, meaning that it will not return untilit has completed its task or has failed while trying.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><LI><B><A HREF="../glossary.html#non-blocking">Non-blocking</A>sockets</B> - Calls on non-blocking sockets return immediately, evenif they cannot complete their task immediately. Although this allowsthe program to do other things while the network operations finish, itrequires that the program repeatedly "poll" Winsock to keep apprised ofits current state.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><LI><B><A HREF="../glossary.html#asynchronous">Asynchronous</A>sockets</B> - These are similar to non-blocking sockets in that callson them will return immediately. The difference is that Winsock sendsthe program a special window message whenever something "interesting"happens.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li><b>Event objects</b> - This is a kind of cross betweennon-blocking and asynchronous sockets. Instead of getting a windowmessage when something interesting happens, Winsock signals a Win32event object. You can block on one or more of these objects with<code>WSAEventSelect()</code>, much like blocking on non-blocking socketswith <code>select()</code>.</p><LI><B>Overlapped I/O</B> - One of <ahref="../general.html#getws2">Winsock 2</a>'s major features is that itties sockets into Win32's unified I/O mechanism. In particular, you cannow use overlapped I/O on sockets, which is intrinsically more efficientthan the above options.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all></UL><p>Further confusing the issue are threads, because each of the abovemechanisms changes in nature when used with threads.</p><p>In trying to find an answer to the "which I/O strategy" question,it becomes apparent that there are only a few major kinds of programs,and the successful ones follow the same patterns. From those patternsand practical experience<img src="../bitmaps/waist-dot.gif" alt="--" width=14 height=6 hspace=2>some personal and some borrowed<img src="../bitmaps/waist-dot.gif" alt="--" width=14 height=6 hspace=2>Ihave derived the following set of heuristics. None of these heuristicsare absolute laws, no one isolated heuristic is sufficient, and theheuristics sometimes conflict. When two heuristics conflict, you needto decide which is more important to your application and ignore theother. However, beware of ignoring a heuristic simply because violatingit does not create noticeable consequences for your program. If you getinto the habit of ignoring a certain heuristic, it becomes useless.</p><p>The heuristics are ordered in terms of compatibility, then speed,and finally functionality. Compatibility is first, because if a givenI/O strategy won't work on the platforms you need to support, it doesn'tmatter how fast or functional it is. Speed is next because performancerequirements are easy to determine, and often important. Functionalityis last, because once you decide the compatibility and speed issues,your choices become much more subjective.</p><p>Note: Aside from the compatibility table in Heuristic 1, this articleno longer covers Windows 3.1 and Windows NT 3.5x issues, as it did inthe past. Hopefully we can call these platforms really and truly deadby now.</p><!-- ------------------------------------------------------------------- --><h4>Heuristic 1: Narrow your choices by deciding yourcompatibility requirements.</h4><p>There are several kinds of I/O strategies mainly because of thelarge number of platforms involved. Winsock was created as a subset ofBSD sockets, and then as new varieties of Windows arrived, Winsock wasextended to take advantage of OS features.</p><table border=0 cellspacing=0 cellpadding=5><tr valign=bottom align=center><td width=100>&nbsp;</td><td>&nbsp;</td><td bgcolor="#F4D7AA"><b>Win9x</b></td><td bgcolor="#F4D7AA"><b>WinCE</b></td><td bgcolor="#F4D7AA"><b>WinNT 4<br>Win2K</b></td><td bgcolor="#F4D7AA"><b>WinNT 3.x</b></td><td bgcolor="#F4D7AA"><b>Win16</b></td><td bgcolor="#F4D7AA"><b>Unix<br>(most)</b></td></tr><tr><td>&nbsp;</td><td bgcolor="#F4D7AA" align=right><b>Blocking Sockets</b></td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td></tr><tr><td>&nbsp;</td><td bgcolor="#F4D7AA" align=right><b>Non-blocking Sockets</b></td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td></tr><tr><td>&nbsp;</td><td bgcolor="#F4D7AA" align=right><b>Asynchronous Sockets</b></td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>no</td></tr><tr><td>&nbsp;</td><td bgcolor="#F4D7AA" align=right><b>Event Objects</b></td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>no</td></tr><tr><td>&nbsp;</td><td bgcolor="#F4D7AA" align=right><b>Overlapped I/O</b></td><td bgcolor="#FBFDB0" align=center>yes<sup>1</sup></td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>no<sup>2</sup></td></tr><tr><td>&nbsp;</td><td bgcolor="#F4D7AA" align=right><b>Threads</b></td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>yes</td><td bgcolor="#FBFDB0" align=center>no</td><td bgcolor="#FBFDB0" align=center>yes<sup>3</sup></td></tr></table><ol><li>The Windows 95 and 98 kernels do not support overlapped I/O,so it is emulated for sockets by the Winsock layer. This means thatprograms that only use overlapped I/O functionality guaranteed by theWinsock spec will run fine on Win9x. If, on the other hand, you strayinto functionality that only WinNT/2000 provides, your application willfail on Win9x. One example of this is calling <code>ReadFile()</code>with a socket: this works fine on NT, but will fail on Win9x.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>If you only need scatter/gather I/O support, BSD sockets providesthis functionality in the <code>readv()</code> and <code>writev()</code>calls. There is no standard Unix mechanism that provides similarefficiencies to Win32's overlapped I/O. Some Unixes provide the<code>aio_*()</code> family of functions (called asynchronous I/O, butnot related to Winsock's asynchronous I/O), but this is not implementedwidely at the moment.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>The Unix world is standardizing on the pthreads library. Pthreadsis roughly equivalent to Win32's thread mechanism, though of course theAPIs are totally different. There are still a lot of older Unix machinesout there with poor, nonstandard or nonexistent threading. If you wantyour code to be portable between Windows and several varieties of Unix,you probably will not be able to use threads unless your target platformlist is very carefully chosen.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all></ol><!-- ------------------------------------------------------------------- --><h4>Heuristic 2: Avoid non-blocking sockets.</h4><p>Non-blocking sockets are almost never necessary, and a good thing, too:their [lack of] performance makes them a poor architecture choice forWindows programs.</p><p>When a socket is set as non-blocking, every Winsock call on that socketwill return immediately, whether it was able to do anything or not. Thisis useful because it lets your program do other things while the networkis busy.</p><p>Most programs don't have something to <i>all</i> the time: they'reusually waiting on user input, or the network, or some other slowthing. For this reason, Winsock provides the <code>select()</code>function which blocks until something happens on one or moresockets. Without <code>select()</code>, you would have to addbusy-loops to your program, which wastes CPU time. Unfortunately,<code>select()</code> isn't all that efficient itself. Four of itsparameters are structures that you must set up each time you callthe function, and three of these require that you loop over them Ntimes after each call, where N is the number of sockets you passed to<code>select()</code>.</p><p>About the only time you should use <code>select()</code> is forcompatibility reasons: the only non-synchronous I/O strategy on Unixand Windows CE is non-blocking sockets, and the only way to block on anon-blocking socket in these OSes is with <code>select()</code>. In allother cases, there are better alternatives.</p><!-- ------------------------------------------------------------------- --><h4>Heuristic 3: Avoid asynchronous sockets in programsthat must deal with high volumes of data.</h4><p>Window messages are the slowest way (aside from <code>select()</code>)to be notified when something happens on a socket. This isn't to say thatWindows message queues are inefficient, just that they're not as efficientas other methods presented below. These queues are also fairly short,so they can fill up if you are not promptly handling window messages.</p><p>The spec says Winsock will try posting notification messages until itsucceeds. Yet, there are persistent reports of window messages being lostin high-traffic situations. I suspect that these are the result of badasynch I/O code, because there are several optimizations in Microsoft'sasynch I/O implementation that make it intolerant of code that doesn'tobey the spec. Who's to say you won't make the same mistake these other

⌨️ 快捷键说明

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