📄 intermediate.html
字号:
u_long host_addr = 0xAC104D58; // 172.16.77.88 u_long net_mask = 0xFFFFE000; // 255.255.224.0 u_long net_addr = host_addr & net_mask; // 172.16.64.0 u_long dir_bcast_addr = net_addr | (~net_mask); // 172.16.95.255</pre><a name="nagle"></a><h5>3.8 - When should I turn off the <a href="glossary.html#Nagle">Nagle</a> algorithm?</h5><p>Generally, almost never.</p><p>Inexperienced Winsockers usually try disabling the Nagle algorithm whenthey are trying to impose some kind of <a href="#packetscheme">packetscheme</a> on a TCP data stream. That is, they want to be able to send,say, two packets, one 40 bytes and the other 60, and have the receiverget a 40-byte packet followed by a separate 60-byte packet. (With theNagle algorithm enabled, TCP will often coalesce these two packetsinto a single 100 byte packet.) Unfortunately, this is futile, for thefollowing reasons:</p><ol><li>Even if the sender manages to send its packets individually,the receiving TCP/IP stack may still coalesce the received packets intoa single packet. This can happen any time the sender can send data fasterthan the receiver can deal with it.<li>Turning off the Nagle algorithm in a client program will notaffect the way that the server sends packets, and vice versa.<li>Routers and other intermediaries on the network can fragmentpackets, and there is no guarantee of "proper" reassembly with streamprotocols.<li>If the network stack runs out of buffers, it may fragment a packet,queuing up as many bytes as it has buffer space for and discarding therest. <li>Winsock is not required to give you all the data it has queuedon a socket even if your <code>recv()</code> call gave Winsock enoughbuffer space. It may require several calls to get all the data queuedon a socket.</ol><p>Aside from these problems, disabling the Nagle algorithm almost alwayscauses a program's throughput to degrade. The only time you should disablethe algorithm is when some other consideration, such as packet timing,is more important than throughput.</p><p>Often, programs that deal with real-time user input will disablethe Nagle algorithm to achieve the snappiest possible response, atthe expense of network bandwidth. Three examples are Telnet clients,X Windows servers, and multiplayer network games. In all three cases,it is more important that there be as little delay between packets aspossible than it is to conserve network bandwidth.</p><p>Note that this is a changable issue: back when network bandwidth wastruly scarce, Telnet clients usually <i>enabled</i> the Nagle algorithmto save on bandwidth. A contributing factor was that user interfaces inthose days tended to be line oriented, whereas modern ones are real-time,with each keystroke potentially changing the entire display. The moralis, consider your application and resources carefully before decidingto disable the Nagle algorithm.</p><p>For more on this topic, see the <ahref="articles/lame-list.html#item19">Lame List</a> and the FAQ article <ahref="articles/effective-tcp.html">How to Use TCP Effectively</a>.</p><a name="threadsafety"></a><h5>3.9 - Is Winsock thread-safe?</h5><p>The Winsock specification does not mandate that a Winsockimplementation be thread-safe, but it does <i>allow</i> an implementorto create a thread-safe version of Winsock.</p><p><a href="reviews/wsnp.html">Bob Quinn</a> says, on this subject:</p><ul><li>"WinSock, <i>any</i> implementation, is thread safe if the WinSockimplementation developer makes it so (it doesn't just happen)."<li>"I don't know of any implementations from Microsoft (or anyother vendors) that are not thread safe."<li>"If a WinSock application developer creates a multi-threaded application that shares sockets among the threads, it is that developer's responsibility to synchronize activities between the threads."</ul><p>By "synchronize activities", I believe Bob means that it may causeproblems if, for example, two threads repeatedly call <code>send()</code>on the same socket. There is no guarantee in the Winsock specificationabout how the data will be interleaved in this situation. Similarly, ifone thread calls <code>closesocket()</code> on a socket, it must somehowsignal other threads using that socket that the socket is now invalid.</p><p>I believe one thread calling <code>send()</code> and another threadcalling <code>recv()</code> on a single socket is safe, but I have nottested this. Hard information, demonstration code and/or anecdotalevidence either way would be appreciated.</p><p>Instead of multiple threads accessing a single socket, you maywant to consider setting up a pair of network I/O queues. Then, giveone thread sole ownership of the socket: this thread sends data fromone I/O queue and enqueues received data on the other. Then otherthreads can access the queues (with suitable synchronization).</p><p>Applications that use some kind of non-synchronous socket typicallyhave some I/O queue already. Of particular interest in this case isoverlapped I/O or I/O completion ports, because these I/O strategiesare also thread-friendly. You can tell Winsock about several OVERLAPPEDblocks, and Winsock will finish sending one before it moves on to thenext. This means you can keep a chain of these OVERLAPPED blocks, eachperhaps added to the chain by a different thread. Each thread can alsocall <code>WSASend()</code> on the block they added, making your mainloop simpler.</p><a name="threaddupdata"></a><h5>3.10 - If two threads in an application call <code>recv()</code> on a socket, will they each get the same data?</h5><p>No. Winsock does not duplicate data among threads.</p><p>Note that if you <i>do</i> call <code>recv()</code> at the same timeon a single socket from two different threads, havoc may result. See<a href="#threadsafety">the previous question</a> for more info.</p><a name="threadnotification"></a><h5>3.11 - Is there any way for two threads to be notified when something happens on a socket?</h5><p>No. If two threads call <code>WSAAsyncSelect()</code> ona single socket, only the thread that made the last call to<code>WSAAsyncSelect()</code> will receive further notificationmessages. Similarly, if two threads call <code>WSAEventSelect()</code>on a socket, only the event object used in the last call willbe signaled when an event occurs on that socket. You also can'tcall <code>WSAAsyncSelect()</code> on a socket in one thread and<code>WSAEventSelect()</code> on that same socket in another thread,because the calls are mutually exclusive for any single socket. Finally,you cannot reliably call <code>select()</code> on a single socket fromtwo threads and get the same notifications in each, because one threadcould clear or cause an event, which would change the events that theother thread sees.</p><a name="modemconn"></a><h5>3.12 - How do I detect if the modem is connected?</h5><p>Although this is not a Winsock question <i>per se</i>, it is sometimesuseful for a Winsock program to only do its thing if the computer isalready connected to the Internet. Before implementing this, however,keep in mind that many computers are not connected to the Internet througha modem. Often, they are connected to a LAN, and that LAN is somehow <ahref="glossary.html#gateway">gatewayed</a> to the Internet. For thesesituations, the following call will fool your program into believing thatthe user either has no Internet connection, or that it is never up.</p><p>Having said that, the Remote Access Service (RAS) API gives anapplication access to the dial-up networking subsystem. In particular,the <code>RasEnumConnections()</code> call lets you easily get a listof the connected modems.</p><a name="username"></a><h5>3.13 - How can I get the local user name?</h5><p>There are a few ways. The easiest is to use the Win32 call<code>GetUserName()</code>. <a href="examples/username.html">[C++Example]</a>.</p><p>The other way is shown in the Microsoft Knowledge Base article<a href="http://support.microsoft.com/support/kb/articles/q155/6/98.asp">Q155698</a>. It is much more complex, and it shows two completelydifferent methods, one for Windows 9x/Windows 3.1 and one for WindowsNT. Unless you need Windows 3.1 support or the LAN Manager domain name(as opposed to the DNS domain name), I suggest you give this articlea miss.</p><a name="dunbug"></a><h5>3.14 - Windows 9x's Dial Up Networking keeps popping up an automatic dial window, even when it isn't necessary. Can I make it stop?</h5><p>On some Windows 9x systems with more than one network interface,Dial Up Networking sometimes pops up an automatic-dial window even whenit is obviously not required. An example of such a setup is a machineon a LAN that also has a modem for connecting to the Internet.</p><p>The most common trigger for the DUN dial window is a Winsock programcalling the <code>gethostbyname()</code> function, which initiates aDNS lookup. Even if the name is that of a LAN machine and there's a DNSserver on the LAN, DUN will still try to bring up the Internet link totry that first.</p><p>If you try messing with the DNS configuration of a <ahref="glossary.html#multi-homed">multihomed</a> Win9x box, it's clearthat the network subsystem just isn't designed to support a local DNSserver in addition to a remote one. The best solution, then, is to justuse straight IP addresses, and write your programs to recognize an IPaddress, so they don't have to call <code>gethostbyname()</code>.</p><p>I've heard that DUN 1.3 and/or the Winsock 2 updates fix thisproblem, but other reports say it doesn't help.</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="newbie.html"><< Information for New Winsockers</a> </td> <td align=right> <a href="advanced.html">Advanced Winsock Issues >></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><</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><<</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><<<</b> Go to my Home Page</a> </font> </td> </tr> </table> </body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -