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

📄 lame-list.html

📁 SDK FAQ集
💻 HTML
📖 第 1 页 / 共 3 页
字号:
Alternative: While a blocking API is in progress in a 16-bit Winsock1.1 application, the proper way to abort is to:<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><ol> <li>Call <code>WSACancelBlockingCall()</code><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Wait until the pending function returns. If the cancellationoccurs before the operation completes, the pending function will failwith the <code>WSAEINTR</code> error, but applications must also be preparedfor success, due to the race condition involved with cancellation.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Close this socket, and all other sockets. Note: the proper closureof a connected stream socket involves:<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><ol type=a> <li>call <code>shutdown()</code> with the <i>how</i> equal to 1<li>loop on <code>recv()</code> until it returns 0 or fails with any error<li>call <code>closesocket()</code> <li>Call <code>WSACleanup()</code> </ol> </ol>This procedure is not relevant to 32-bit Winsock 2 applications,since they really block, so calling <code>WSACancelBlockingCall()</code>from the same thread is impossible. (Therefore, this call is deprecatedunder Winsock 2.) However, step 3 above is still useful for shuttingdown a socket cleanly.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Out of band data. <i>Intensely lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: TCP can't do Out of Band (OOB) data reliably. If that isn'tenough, there are incompatible differences in the implementation atthe protocol level (in the urgent pointer offset). Berkeley (BSD)Unix implements <a href="../../rfcs/official.html#rfc793">RFC793</a> literally, and many others implement the corrected <ahref="../../rfcs/official.html#rfc1122">RFC 1122</a> version. (Someversions also allow multiple OOB data bytes by using the start of theMAC frame as the starting point for the offset.) If two TCP hosts havedifferent OOB versions, they cannot send OOB data to each other.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Ideally, you can use a separate socket for urgent data,although in reality it is inescapable sometimes. Some protocols require it(<a href="#item7">see item 7</a>), in which case you need to minimizeyour dependence, or beef up your technical support staff to handleuser calls.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Calling <code>strlen()</code> on a hostent structure's ipaddress, then truncating it to four bytes, thereby overwriting part of<code>malloc()</code>'s heap header. <i>In all my years of observing lameness,I have seldom seen something this lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: This doesn't really need a reason, does it?<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Clearly, the only alternative is a brain transplant.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><a name=item12> <li>Polling with <code>recv(MSG_PEEK)</code> todetermine when a complete message has arrived. <i>Thrashing in a seaof lameness.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: A stream socket (TCP) does not preserve message boundaries(<a href="#item20">see item 20</a>). An application that uses<code>recv(MSG_PEEK)</code> or <code>ioctlsocket(FIONREAD)</code> to wait fora complete message to arrive, may never succeed. One reason might bethe internal service provider's buffering; if the bytes in a "message"straddle a system buffer boundary, the Winsock may never report thebytes that exist in other buffers.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Don't use peek reads. Always read data into yourapplication buffers, and examine the data there.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Passing a longer buffer length than the actual buffersize since you know you won't receive more than the actual buffersize. <i>Universally lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: Winsock implementations often check buffers for readability orwritability before using them to avoid Protection Faults. When a bufferlength is longer than the actual buffer length, this check will fail,so the function call will fail with <code>WSAEFAULT</code>.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Always pass a legitimate buffer length.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Bounding every set of operations with calls to<code>WSAStartup()</code> and <code>WSACleanup()</code>. <i>Pushing the lamenessenvelope.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: This is not illegal, as long as each <code>WSAStartup()</code>has a matching call to <code>WSACleanup()</code>, but it is more work thannecessary.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: In a DLL, custom control or class library, it is possibleto register the calling client based on a unique task handle or processID. This allows automatic registration without duplication. Automaticde-registration can occur when a process closes its last socket. Thisis even easier if you use the process notification mechanisms availablein the 32-bit environment.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Ignoring API errors. <i>Glaringly lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: Error values are your friends! When a function fails, theerror value returned by <code>WSAGetLastError()</code> or included in anasynchronous message can tell you <i>why</i> it failed. Based on thefunction that failed, and the socket state, you can often infer whathappened, why, and what to do about it.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Check for error values, and write your applications toanticipate them, and handle them gracefully when appropriate. When afatal error occurs, always display an error message that shows:<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all> <ul type=disc> <li>the function that failed <li>the Winsock errornumber, and/or macro <li>a short description of the error meaning<li>suggestions for how to remedy, when possible </ul> <img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>Calling <code>recv(MSG_PEEK)</code> in response to an <code>FD_READ</code>async notification message. <i>Profoundly lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: It's redundant. It's redundant.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Make a plain <code>recv()</code> call in response to an<code>FD_READ</code> message. Even if it fails with <code>WSAEWOULDBLOCK</code>,that error is easy to ignore, and you are guaranteed to get another<code>FD_READ</code> message later since there is data pending.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><a name=item17> <li>Installing an empty blocking hook that just returns<code>FALSE</code>. <i>Floundering in an endless desert of lameness.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: One of the primary purposes of the blocking hook functionwas to provide a mechanism for an application with a pending blockingoperation to yield. By returning <code>FALSE</code> from the blocking hookfunction, you defeat this purpose and your application will preventmultitasking in the non-preemptive 16-bit Windows environment. This mayalso prevent some Winsock implementations from completing the pendingnetwork operation.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Typically this hack is done to try to prevent reentrantmessages. There are better ways to do this, like subclassing the activewindow, although, admittedly, preventing reentrant messages is not aneasy problem to avoid.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Note that this is not an issue for Winsock 2 applications, sinceblocking hooks are now a thing of the past! (Good riddance.)<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><a name=item18> <li>Client applications that bind to a specificport. <i>Suffocating in self lameness.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: By definition, client applications actively initiate anetwork communication, unlike server applications which passively waitfor communication. A server must <code>bind()</code> to a specific port whichis known to clients that need to use the service, however, a client neednot <code>bind()</code> its socket to a specific port in order to communicatewith a server.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Not only is it unnecessary for all but a very few applicationprotocols, it is dangerous for a client to <code>bind()</code> to a specificport number. There is a danger in conflicting with another socketthat is already using the port number, which would cause the call to<code>bind()</code> to fail with <code>WSAEADDRINUSE</code>.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Simply let the Winsock implementation assign the localport number implicitly when you call <code>connect()</code> (on stream ordatagram sockets), or <code>sendto()</code> (on datagram sockets).<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><a name=item19> <li>Nagle challenged applications. <i>Perilouslyteetering on the edge of a vast chasm of lameness.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: The Nagle algorithm reduces trivial network traffic. In anutshell, the algorithm says don't send a TCP segment until either:<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><ul type=disc> <li>all outstanding TCP segments have been acknowledged;or <li>there's a full TCP segment ready to send </ul>A "Nagle challenged application" is one that cannot wait until eitherof these conditions occurs, but has such time-critical data that it mustsend continuously. This results in wasteful network traffic.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Don't write applications that depend on the immediatedata echo from the remote TCP host.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><a name=item20> <li>Assuming stream sockets maintain message frameboundaries. <i>Mind bogglingly lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Reason: Stream sockets (TCP) are called stream sockets, becausethey provide data streams (duh). As such, the largest message sizean application can ever depend on is one-byte in length. No more, noless. This means that with any call to <code>send()</code> or <code>recv()</code>,the Winsock implementation may transfer any number of bytes less thanthe buffer length specified.<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>Alternative: Whether you use a blocking or non-blocking socket,on success you should always compare the return from <code>send()</code>or <code>recv()</code> with the value you expected. If it is less thanyou expected, you need to adjust the buffer length, and pointer, foranother function call (which may occur asynchronously, if you are usingasynchronous operation mode).<img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all><li>16-bit DLLs that call <code>WSACleanup()</code> from theirWEP. <i>Inconceivably lame.</i><img src="../bitmaps/dot-clear.gif" alt="" width=1 height=30 align=top> <br clear=all>

⌨️ 快捷键说明

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