📄 ch18.htm
字号:
<html>
<head>
<title>Special Edition Using Visual C++ 5 - Chapter 18</title>
<link rel="Next" href="ch19.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/ch19.htm">
<link rel="Previous" href="ch17.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/ch17.htm"></head>
<body bgcolor="#FFFFFF" text="#000000">
<h2><b> Chapter 18</b></h2>
<h2><b> Sockets, MAPI, and the
Internet</b></h2>
<hr>
<p>There are a number of ways for your applications to communicate with other applications through a network like the Internet. This chapter introduces you to the concepts involved with these programming techniques. Subsequent
chapters will cover some of these concepts in more detail.</p>
<p>Before the Windows operating system even existed, the Internet existed. As it grew, it became the largest TCP/IP network in the world. The early sites were UNIX machines, and a set of
conventions called Berkeley sockets became the standard for TCP/IP communication between UNIX machines on the Internet. Other operating systems implemented TCP/IP communications, too, which contributed immensely to the growth of the Internet. On those
operating systems, things were starting to get messy, with a wide variety of proprietary implementations of TCP/IP, when a group of over 20 vendors banded together to create the Winsock specification.</p>
<ul>
<li> <b>Using Windows Sockets
(Winsock)</b></p>
<p> Describes the role that Winsock.dll plays in developing communications applications.</p>
<li> <b>Messaging API (MAPI)</b></p>
<p> The capability to send messages is a must to receive a Windows 95 stamp of approval from Microsoft.
This section shows you how to use this powerful API.</p>
<li> <b>New Internet Classes in Visual C++ 4.2</b></p>
<p> These powerful classes make Internet development fast and easy.</p>
<li> <b>Internet Server API (ISAPI) Classes</b></p>
<p> An Application
Programmer Interface is a collection of utility functions collected for a similar purpose. The Internet Server<b> </b>API puts your World Wide Web server under your control.</p>
</ul>
<h3><b>Using Windows Sockets</b></h3>
<p>The Winsock specification
defines the interface to a DLL, typically called WINSOCK.DLL or WSOCK32.DLL. Vendors write the code for the functions themselves. Applications can call the functions, confident that the name, parameter meaning, and final behavior of the function is the
same no matter which DLL is installed on the machine. For example, the DLLs included with Windows 95 and Windows NT are not the same at all, but a 32-bit Winsock application can run unchanged on a Windows 95 or Windows NT machine, calling the Winsock
functions in the appropriate DLL.</p>
<blockquote><p><img src="note.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/note.gif">
<p>Winsock is not confined to TCP/IP communication. IPX/SPX support is the second protocol supported, and there will be others. For more information, check the Winsock specification
itself. The Stardust Labs Winsock Resource Page at <a href="tppmsgs/msgs0.htm#16" tppabs="http://www.stardust.com/wsresource/" target="_top"><b>http://www.stardust.com/wsresource/</b></a> is a great starting point.</p>
<p><img src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>
<p>An important concept in
sockets programming is a socket's <i>port</i>. Every site on the Internet has a numeric address called an <i>IP address,</i> typically written as four numbers separated by dots: <b>198.53.145.3</b>, for example. Programs running on that machine are all
willing to talk, using sockets, to other machines. If a request arrives at <b>198.53.145.3</b>, which program should handle it?</p>
<p>Requests arrive at the machine carrying a <i>port number,</i> a number from 1,024 and up that indicates for which program
the request is intended. Some port numbers are reserved for standard use; for example, port 80 is traditionally used by Web servers to listen for Web document requests from client programs like Netscape Navigator.</p>
<p>Most socket work is
<i>connection-based</i>: the two programs form a connection with a socket at each end and then send and receive data along the connection. Some applications prefer to send the data without a connection, but there is no guarantee that this data arrives. The
classic example is a time server that sends out the current time to every machine near it, regularly, without waiting until it is asked. The delay in establishing a connection might make the time sent through the connection outdated, so it makes sense in
this case to use a connectionless approach.</p>
<p><b>Winsock in MFC</b></p>
<p>At first, sockets programming in Visual C++ meant making API calls into the DLL. Many developers built socket classes to encapsulate these calls. Visual C++ 2.1 introduced two
new classes: <font color="#008000">CAsyncSocket</font> and <font color="#008000">CSocket</font>, which inherits from <font color="#008000">CAsyncSocket</font>. These classes handle the API calls for you, including the startup and cleanup calls that would
otherwise be easy to forget.</p>
<p>Windows programming is <i>asynchronous</i>: there are lots of different things going on at the same time. In older versions of Windows, if one part of an application got stuck in a loop or otherwise hung up, the entire
application—and sometimes the entire operating system—would stick or hang with it. This was obviously something to be avoided at all costs. Yet a socket call, perhaps a call to read some information through a TCP/IP connection to another site on
the Internet, might take a long time to complete. (A function that is waiting to send or receive information on a socket is said to be <i>blocking</i>.) There are three ways around this problem:</p>
<ol>
<li><p> Put the function that might block in a
thread of its own. The thread will block, but the rest of the application will carry on.</p>
<li><p> Have the function return immediately after making the request, and have another function check regularly (<i>poll</i> the socket) to see if the request has
completed.</p>
<li><p> Have the function return immediately, and send a Windows message when the request has completed.</p>
</ol>
<p>Option 1 was not available until recently, and Option 2 is inefficient under Windows. So most Winsock programming adopts
Option 3. The class <font color="#008000">CAsyncSocket</font> implements this approach. For example, to send a string across a connected socket to another site on the Internet, you call that socket's <font color="#008000">Send()</font> function. <font
color="#008000">Send()</font> doesn't necessarily send any data at all; it tries to, but if the socket isn't ready and waiting, <font color="#008000">Send()</font> just returns. When the socket is ready, a message is sent to the socket window, which
catches it and sends the data across. This is called <i>asynchronous Winsock programming.</i></p>
<blockquote><p><img src="note.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/note.gif">
<p>Winsock programming is not a simple topic; entire books have been written on it. One you might like to look at is Que's
<i>Developing Internet Applications in Visual C++ </i>ISBN 0-7897-0213-4<i>.</i> If you decide that this low-level sockets programming is the way to go, building standard programs is a good way to learn the process.</p>
<p><img
src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>
<p><b> </b><b><i>CAsyncSocket</i></b></p>
<p>The CAsyncSocket class is a wrapper class for the asynchronous Winsock calls. It has a number of useful functions, which facilitate using the Winsock API. Table 18.1 lists the
CAsyncSocket member funtions and responsibilities.</p>
<p><i>Table 18.1—CAsyncSocket Member Functions</i></p>
<table border>
<tr>
<td>
<p><b>Method Name</b></p>
<td>
<p><b>Description</b></p>
<tr>
<td>
<p>Accept</p>
<td>
<p>handles an incoming
connection on a listening socket, filling a new socket with the address information.</p>
<tr>
<td>
<pre><font color="#008000">AsyncSelect</font></pre>
<td>
<p>Requests that a Windows message be sent when a socket is ready.</p>
<tr>
<td>
<pre><font
color="#008000">Attach</font></pre>
<td>
<p>Attaches a socket handle to a <font color="#008000">CAsyncSocket</font> instance, so that it can form a connection to another machine.</p>
<tr>
<td>
<pre><font color="#008000">Bind</font></pre>
<td>
<p>Associates
an address with a socket.</p>
<tr>
<td>
<pre><font color="#008000">Close</font></pre>
<td>
<p>Closes the socket.</p>
<tr>
<td>
<pre><font color="#008000">Connect</font></pre>
<td>
<p>Connects the socket to a remote address and port.</p>
<tr>
<td>
<pre><font color="#008000">Create</font></pre>
<td>
<p>Completes the initialization process begun by the constructor.</p>
<tr>
<td>
<pre><font color="#008000">Detach</font></pre>
<td>
<p>Detaches a previously attached socket handle.</p>
<tr>
<td>
<pre><font color="#008000">FromHandle</font></pre>
<td>
<p>Returns a pointer to the <font color="#008000">CAsyncSocket</font> attached to the handle it was passed.</p>
<tr>
<td>
<pre><font color="#008000">GetLastError</font></pre>
<td>
<p>Returns the error
code of the socket. Call GetLastError after an operation fails, to find out why.</p>
<tr>
<td>
<pre><font color="#008000">GetPeerName</font> </p>
<td>
<p>Finds the IP address and port number of the remote socket that the calling object socket is connected
to, or fills a socket address structure with that information.</p>
<tr>
<td>
<pre><font color="#008000">GetSockName</font></pre>
<td>
<p>Returns the IP address and port number of <font color="#008000">this</font> socket, or fills a socket address structure
with that information.</p>
<tr>
<td>
<pre><font color="#008000">GetSockOpt</font></pre>
<td>
<p>Returns the socket options that are currently set.</p>
<tr>
<td>
<pre><font color="#008000">IOCtl</font></pre>
<td>
<p>Sets the mode of the socket; most
commonly, to blocking or non-blocking.</p>
<tr>
<td>
<pre><font color="#008000">Listen</font></pre>
<td>
<p>Instructs a socket to watch for incoming connections.</p>
<tr>
<td>
<pre><font color="#008000">OnAccept</font></pre>
<td>
<p>Handles the Windows
message generated when a socket has an incoming connection to accept. Often overridden by derived classes.</p>
<tr>
<td>
<pre><font color="#008000">OnClose</font></pre>
<td>
<p>Handles the Windows message generated when a socket closes. Often overridden by
derived classes.</p>
<tr>
<td>
<pre><font color="#008000">OnConnect</font></pre>
<td>
<p>Handles the Windows message generated when a socket becomes connected or a connection attempt ends in failure. Often overridden by derived classes.</p>
<tr>
<td>
<pre><font color="#008000">OnOutOfBandData</font></pre>
<td>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -