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

📄 newbie.html

📁 SDK FAQ集
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<p>There is a special address called the <i>loopback</i> or<i>localhost</i> address, 127.0.0.1. This lets two programs runningon a single machine talk to each other. The server usually listens forconnections on all available interfaces, and the client connects to thelocalhost address. (See the <a href=examples/index.html>Examples</a> section forbasic client and server program code.)</p><p>If you have Internet access from your development machine, you'realready set up for this.</p><p>If you don't, you can try installing Dial Up Networking and pointingit at an unused serial port. This can be quirky, but it's possibleto limp by with this method. The main problems are when DUN decidesit needs to dial the modem, and finds that there is no modem on theport you chose. To minimize this problem, never use name lookup callslike <code>gethostbyname()</code> and turn off DUN's "automatic dial"feature.</p><p>Be warned: behavior through the loopback interface may well bedifferent from behavior on a network, if only because conditions aremuch simpler within a single machine than over a LAN or WAN. You shouldtry to test your application on a real network, even if you do primarydevelopment on a single machine.</p><a name="howclose"></a><h5>2.11 - What's the proper way to close a TCP socket?</h5><p>The proper sequence for closing a TCP connection is:</p><ol><li>Finish sending data.<li>Call <code>shutdown()</code> with the <i>how</i> parameter set to 1.<li>Loop on <code>recv()</code> until it returns 0.<li>Call <code>closesocket()</code>.</ol><p>Skipping the first and third steps above can cause data loss.</p><p>Nonblocking or asynchronous sockets complicate the first and thirdsteps. You can either build "finish sending/receiving" logic intoyour normal I/O loop, or you can temporarily put the socket inblocking mode and do the last bits of I/O that way. The proper choicedepends on your program's architecture and requirements.</p><a name="hownotclose"></a><h5>2.12 - Is it possible to close the connection "abnormally"?</h5><p>Sure, but it's an evil thing to do. :) The simplest way is to set the<code>SO_LINGER</code> flag to 0 with the <code>setsockopt()</code> callbefore you call <code>closesocket()</code>. Another method is to call<code>shutdown()</code> with the <code>how</code> parameter set to 2("both directions"), possibly followed by a <code>closesocket()</code>call.</p><p>"Slamming the connection shut" is only justifiable in a very smallnumber of cases. You must have fairly deep knowledge of the way TCPworks before you can properly decide to use this technique. Generally,the perceived need to slam the connection shut comes from a brokenprogram, either yours or the remote peer. I recommend that you try tofix the broken program so you don't have to resort to such a questionabletechnique.</p><a name="normalclose"></a><h5>2.13 - How do I detect when my TCP connection is closed?</h5><p>All of the I/O strategies discussed in the <ahref=articles/io-strategies.html>I/O strategies article</a> have some way ofindicating that the connection is closed.</p><p>First, keep in mind that TCP is a full-duplex network protocol.That means that you can close the connection half-way and still send dataon the other half. An example is a web browser: it sends a short requestto the web server, then closes its half of the connection. The web serverthen sends back the requested data on the other half of the connection,and closes its sending side, which terminates the TCP session.</p><p>Normal TCP programs only close the sending half, which the remotepeer perceives as the receiving half. So, what you normally want todetect is whether the remote peer closed its sending half, meaning youwon't be receiving data from them any more.</p><p>With asynchronous sockets, Winsock sends you an <code>FD_CLOSE</code>message when the connection drops. Event objects are similar: the systemsignals the event object with an <code>FD_CLOSE</code> notification.</p><p>With blocking and non-blocking sockets, you probably have a loop thatcalls <code>recv()</code> on that socket. <code>recv()</code> returns0 when the remote peer closes the connection. As you would expect,if you are using <code>select()</code>, the SOCKET descriptor in the<code>read_fds</code> parameter gets set when the connection drops. Asnormal, you'll call <code>recv()</code> and see the 0 return value.</p><p>As you might have guessed from the discussion above, it is alsopossible to close the <i>receiving</i> half of the connection. This won'tstop the remote peer from sending you data, but it will stop Winsockfrom telling you about it. Winsock may just silently drop the data onthe floor, or it may send an error back to the remote peer.</p><p>See <a href="#abnormalclose">below</a> for information on handlingabnormal disconnects.</p><a name="abnormalclose"></a><h5>2.14 - How do I detect an abnormal network disconnect?</h5><p>The <a href="#normalclose">previous question</a> deals with detectingwhen a protocol connection is dropped normally, but what if you wantto detect other problems, like unplugged network cables or crashedworkstations? In these cases, the failure prevents notifying the remotepeer that something is wrong. My feeling is that this is usually afeature, because the broken component might get fixed before anyonenotices, so why force everyone to restart?</p><p>If you have a situation where you must be able to detect all networkfailures, you have two options:</p><p>The first option is to give the protocol a command/responsestructure: one host sends a command and expects a prompt responsefrom the other host when the command is received or acted upon. If theresponse does not arrive, the connection is assumed to be dead, or atleast faulty.</p><p>The second option is to add an "echo" function to your protocol,where one host (usually the client) is expected to periodically send outan "are you still there?" packet to the other host, which it must promptlyacknowledge. If the echo-sending host doesn't receive its response or thereceiving host fails to see an echo request for a certain period of time,the program can assume that the connection is bad or the remote hosthas gone down.</p><p>If you choose the "echo" alternative, avoid the temptation to usethe ICMP "ping" facility for this. If you did it this way, you wouldhave to send pings from both sides, because Microsoft stacks won't letyou see the other side's echo requests, only responses to your own echorequests. Another problem with ping is that it's outside your protocol,so it won't detect a failed TCP connection if the hardware connectionremains viable. A final problem with the ping technique is that ICMP isan unreliable protocol: does it make a whole lot of sense to use anunreliable protocol to add an assurance of reliability to anotherprotocol?</p><p>Another option you should not bother with is the TCP keepalivemechanism. This is a way to tell the stack to send a packet out overthe connection at specific intervals whether there's real data to sendor not. If the remote host is up, it will send back a similar replypacket. If the TCP connection is no longer valid (e.g. the remote hosthas rebooted since the last keepalive), the remote host will send backa reset packet, killing the local host's connection. If the remote hostis down, the local host's TCP stack will time out waiting for the replyand kill the connection.</p><p>There are two problems with keepalives:</p><ol><li>Only Windows 2000 allows you to change the keepalive time ona per-process basis. On older versions of Windows, changing thekeepalive time changes it for all applications on the machine that usekeepalives.<img src="./bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Each keepalive packet is 40 bytes of more-or-less useless data,and there's one sent each direction as long as the connection remainsvalid. Contrast this with a command/response type of protocol, wherethere is effectively no useless data: all packets are meaningful. Infairness, however, TCP keepalives are less wasteful on Windows 2000 thanthe "are you still there" strategy above.<img src="./bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all></ol><p>Note that different types of networks handle physical disconnectiondifferently. Ethernet, for example, establishes no link-level connection,so if you unplug the network cable, a remote host can't tell that itspeer is physically unable to communicate. By contrast, a dropped PPP linkcauses a detectable failure at the link layer, which propagates up tothe Winsock layer for your program to detect.</p><a name="timeout"></a><h5>2.15 - How can I change the timeout for a Winsock function?</h5><p>Some of the blocking Winsock functions (e.g. <code>connect()</code>)have a timeout embedded into them. The theory behind this is that onlythe stack has all the information necessary to set a proper timeout.Yet, some people find that the value the stack uses is too long fortheir application; it can be a minute or longer.</p><p>Under Winsock 2, you can set the <code>SO_SNDTIMEO</code> and<code>SO_RCVTIMEO</code> options with <code>setsockopt()</code> to changethe timeouts for <code>send()</code> and <code>recv()</code>.</p><p>Unfortunately, the Winsock spec does not document a way to changemany other timeout values, and the above advice doesn't apply toWinsock 1.1.</p><p>The solution is to avoid blocking sockets altogether. All of thenon-blocking socket methods lend themselves to timeouts:</p><ul type=disc><li><b>Non-blocking sockets with <code>select()</code></b><img src="./bitmaps/waist-dot.gif" alt="-" width=7 height=6 hspace=2> The fifth parameter to the <code>select()</code> function is a timeoutvalue.<li><b>Asynchronous sockets</b> <img src="./bitmaps/waist-dot.gif" alt="-" width=7 height=6 hspace=2> Use the Windows API<code>SetTimer()</code>.<li><b>Event objects</b> <img src="./bitmaps/waist-dot.gif" alt="-" width=7 height=6 hspace=2> In addition to the Winsock event object,have your networking code also block on a regular Win32 semaphore thatis signalled by a separate thread that calls the Win32 <code>Sleep()</code>function.<li><b>Waitable Timers</b> <img src="./bitmaps/waist-dot.gif" alt="-" width=7 height=6 hspace=2> These are a new feature inWindows 98 and NT 4.0 SP3 and higher. A waitable timer is anobject like a semaphore, except that the OS signals it at a futuretime that you specify. You create them with the Win32 function<code>CreateWaitableTimers()</code>. So, you could wait on a 5-secondtimer as well as your event objects; if nothing happens on the socketswithin 5 seconds, Windows will signal the timer, thus breaking you outof the <code>WaitForMultipleObjects()</code> call.</p></ul><p>Note that with asynchronous and non-blocking sockets, you may be ableto avoid handling timeouts altogether. Your program continues working evenwhile Winsock is busy. So, you can leave it up to the user to cancel anoperation that's taking too long, or just let Winsock's natural timeoutexpire rather than taking over this functionality in your code.</p>		</td>	</tr></table><!--  ---- Document Footer ----  --><hr noshade size=1 color=#404040><table cellpadding=5 cellspacing=0 border=0 width=95% align=center> 	<tr>		<td align=left>		    <a href="general.html">&lt;&lt; General Winsock Information</a>		</td>		<td align=right>		    <a href="intermediate.html">Intermediate Winsock Issues &gt;&gt;</a>		</td>	</tr>	<tr>		<td align=left>			<i>Last modified on 29 April 2000 at 15:52 UTC-7</i>		</td>		<td align=right>			<font size=-1>Please send corrections to <a href="mailto:tangent@cyberport.com">tangent@cyberport.com</a>.</font>		</td>	</tr>	</table>	<table cellpadding=5 cellspacing=0 border=0 width=95% align=center> 	<tr>		<td align=left width=33%>			<font size=-1>				<a href="index.html"><b>&lt;</b> Go to the main FAQ page</a>			</font>		</td>		<td width=33%>			<font size=-1>			<center>				<a href="http://www.cyberport.com/~tangent/programming"><b>&lt;&lt;</b> Go to my Programming pages</a>			</center>			</font>		</td>		<td align=right width=33%>			<font size=-1>				<a href="http://www.cyberport.com/~tangent/"><b>&lt;&lt;&lt;</b> Go to my Home Page</a>			</font>		</td>	</tr>	</table>	</body></html>

⌨️ 快捷键说明

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