P1: 50
Mayfield WL040/Bidgoli-Vol III-Ch-52 June 23, 2003 16:35 Char Count= 0
642 VISUALC++ (MICROSOFT)CSocketFileobject using aCArchiveto simplify com-
munication with the client. Then a loop is entered in
which the date/time is retrieved, formatted as a string,
and sent to the client. At the end of the loop, the thread
is put to sleep for 1 s (1,000 ms) before the next string
is sent. This loop will continue until the user terminates
the server program or until the connection to the client
is closed. Note the use ofTRY, CATCH, andENDCATCH;
these are macros that implement MFC’s own form of ex-
ception handling, which is used byCSocketand its parent
classCAsyncSocket. The use ofTRYandCATCHblocks
in the thread function keep the program from terminating
abnormally when the connection to the client is broken.Final Changes
The last modification to the project is to add a#in-
cludeand to declare global variables that will be used
byOnInitialUpdateandServerThreadProc. Insert
these statements following the default#includestate-
ments inMFCServerView.cpp:#include <time.h>
SOCKET hSocket;
int NumOfClients = 0;Build the Project
Build (i.e., compile and link) the project. Do not run it un-
til the client program, described below, has been written
and built.An Example WinSock Client
The client program presented communicates with the
server program described above. It uses many of the same
ideas and techniques as the server. Before beginning work
on the client program, make sure to close the server pro-
gram workspace.Create the Client Project
Click on “New” from the IDE menu bar, and then select the
“Project” tab in the dialog box. Choose “MFC AppWizard
(exe)” as the type of project, and choose a project directory
for the project name. (For the duration of this description,
it will be assumed that the project is namedMFCClient.)
Click on the “OK” button to begin the AppWizard.
In the AppWizard, choose the single-document inter-
face (in AppWizard step 1), uncheck the “Printing and
print preview” checkbox (in step 4), check the “Win-
dows sockets” checkbox (in step 4), and chooseCEd-
itViewfrom the dropdown list of view base class choices
(in step 6). Accept the defaults for all other AppWizard
choices.Create a Message Handler
Invoke the ClassWizard by clicking on “View” from the
IDE menu bar, then on “ClassWizard.” From the “Class
name” dropdown list chooseCMFCClientView, from the
“Object IDs” list choose CMFCClientView, and from
the “Messages” list chooseOnInitialUpdate. Click on
the “Add Function” button, andOnInitialUpdateap-
pears in the “Member functions” list at the bottom ofthe ClassWizard window. Double-click the nameOnIni-
tialUpdatein the “Member functions” list to be taken to
the newly created method implementation in the source
editor. Insert the statements shown in Listing 3 after the
other statements that are already inOnInitialUpdate.Listing 3:OnInitalUpdate body for example WinSock client
program.
(1) CSocket serverSock;
(2)
(3) // Create the listening socket.
(4) if (!serverSock.Create()) {
(5) MessageBox("Create Error");
(6) return;
(7) }
(8)
(9) // Connect to the server.
(10) if (!serverSock.Connect("localhost",
5555)) {
(11) MessageBox("Connect Error");
(12) return;
(13) }
(14)
(15) // This is needed to make
multithreading work.
(16) hSocket = serverSock.Detach();
(17)
(18) // Begin the server thread, passing
a handle to the view.
(19) AfxBeginThread(ClientThreadProc,
GetSafeHwnd());The major difference between this implementation of
OnInitialUpdateand its counterpart in the server pro-
gram is the call to the methodConnectin line 10. In
this example it is assumed that the server and client are
running on the same computer, so “localhost” has been
used as the first argument forConnect; if the server
and client are on different computers, the IP address or
host name of the server computer should be substituted.
The second argument ofConnectis a port number that
matches the one used in the server program. Notice that
the client program also is multithreaded, even though it
will connect to only one server. Multithreading is used
here so that the client program can continue to process
Windows messages while it communicates with the server
program.Create the Worker Thread Procedure
Insert the implementation of the global functionClient-
ThreadProc shown as Listing 4 into the file MFC-
ClientView.cpp just above the implementation of
OnInitialUpdate. The purpose of this function is to re-
ceive strings from the server socket and to display them
in the view.Listing 4:Thread procedure from example WinSock client
program.
(1) UINT ClientThreadProc(LPVOID pParam) {
(2) CSocket serverSock;
(3)