Click here to Skip to main content
15,884,298 members
Articles / Desktop Programming / MFC

CSPServer, State-based Protocol Server Class

Rate me:
Please Sign up or sign in to vote.
4.88/5 (14 votes)
11 Mar 20038 min read 145K   1.4K   71  
Class framework for creating client/server protocol servers
<!--------------------------------------------------------------------------->
<!--                           INTRODUCTION                                

 The Code Project article submission template (HTML version)

Using this template will help us post your article sooner. To use, just 
follow the 3 easy steps below:
 
     1. Fill in the article description details
     2. Add links to your images and downloads
     3. Include the main article text

That's all there is to it! All formatting will be done by our submission
scripts and style sheets. 

-->
<!--------------------------------------------------------------------------->
<!--                        IGNORE THIS SECTION                            -->
<html>

<head>
<title>The Code Project</title>
<style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
<link rel="stylesheet" type="text/css" href="http://www.codeproject.com/styles/global.css">
</head>

<body bgcolor="#FFFFFF" color="#000000">
<!--------------------------------------------------------------------------->
<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->

<pre>
Title:       CSPServer, State-based Protocol Server Class
Author:      Hector Santos
Email:       codeproject@winserver.com
Environment: VC++ 5.0-6.0, NT 4.0, Win95/98
Keywords:    Internet, Class, Protocol Server, Socket
Level:       Intermediate
Description: Class framework for creating client/server protocol servers
Section      C++/MFC
SubSection   Internet
</pre>
<!-------------------------------     STEP 2      --------------------------->
<!--  Include download and sample image information.                       -->

<ul class="download">
  <li><a href="cspserver_src.zip">Download source - 22 Kb</a></li>
</ul>

<h2>Introduction</h2>

<p><code>CSPServer</code> is a VC++ class which makes it relatively easy to create solid,
multi-threaded client/server state-based protocol servers (SPS).&nbsp; Common existing
standard client/server SPS systems are SMTP, POP3, FTP, NNTP and others systems which
millions of people use every day on the internet.&nbsp; </p>

<p><code>CSPServer</code> gives you a time-tested, well engineered framework to create
your own standard protocol server or a new protocol server that suits your needs.&nbsp; <code>CSPServer</code>
is used in Santronics Software's intranet hosting product, <em><strong>Wildcat!
Interactive Net Server</strong></em> (<a href="http://www.santronics.com">http://www.santronics.com</a>)
to provide an&nbsp; integrated multiple protocol intranet hosting system.&nbsp;&nbsp;
Proprietary virtual communications technology was removed to make a public socket-based
only version of <code>CSPServer</code>.&nbsp; </p>

<p>This article will explain how to use the <code>CSPServer</code> class with working SPS
examples.&nbsp; This is the author's first CodeProject article subsmission, so all
commentators and critics are welcome.</p>

<h2>Background </h2>

<p>A State-based Protocol Server or SPS is client/server methodology where by a client
application connects to a server application to begin a text based &quot;controlled&quot;
conversation.&nbsp; This controlled conversation is often called the &quot;State
Machine.&quot;&nbsp;&nbsp;</p>

<p>In a state machine, a connected client will issue a command and then wait for a server
response to the command.&nbsp; In a properly designed state machine, the client can not
continue with additional commands until a response was provided by the server for the
current command.&nbsp; <font color="#0000FF"><em>It is very important to understand that
all conversations in a state machine begins with the client issuing commands. The server
will never send data or information to the client unless it was requested or in response
to a client command.&nbsp; </em></font></p>

<p><code>CSPServer</code> offers a framework to create your own client/server state
machine conversation for your client/server application.&nbsp; </p>

<p>If you understand this basic concept, you can skip the next background section which
illustrates a SPS using a standard SMTP server.</p>

<h3>Example standard SPS - SMTP</h3>

<p>If you ever connected to standard SPS such as SMTP, POP3, FTP, NNTP etc, the first line
you see is the welcome line.&nbsp;&nbsp; The best way to see this is to use a standard
TELNET client such as the one that comes with Windows.&nbsp; For example, to connect to
the Microsoft SMTP server (port 25) using telnet, type the following:</p>

<blockquote>
  <p><em>Telnet maila.microsoft.com 25</em></p>
</blockquote>

<p>If successful, you will see the welcome line.&nbsp; You can type HELP to see the
available commands.&nbsp; Most standard SPS systems will provide HELP information on the
available commands.</p>

<p>However, SPS systems are ultimately designed for automated applications, not human
interaction.&nbsp; Client software are used to automate the process, such as sending an
email.&nbsp;&nbsp; The following illustrates what typically happens when you want to send
an email to anyone in the world.</p>

<p>Example SMTP client/server session:</p>

<p>Lets assume the target address for the email is <a href="mailto:gbush@whitehouse.gov">gbush@whitehouse.gov</a>&nbsp;
and lets assume you are using Outlook Express (OE) to create and send the email.&nbsp; OE
has a built-in SMTP client component which is used to send mail to a SMTP server.&nbsp; </p>

<p>The following are the steps taken to send the email. 

<ol>
  <li>OE smtp client obtains the MX record for the domain whitehouse.gov. The MX provides the
    IP address location of the SMTP server. The client will then connect to the IP address
    defined by the MX record.</li>
  <li>The client waits for the welcome response and then issues the HELO or EHLO command.
    &nbsp;&nbsp; The client waits for a positive response.</li>
  <li>The client issues the command MAIL FROM: &lt;youraddress&gt; and waits for a positive
    response.&nbsp; </li>
  <li>The client issues the command RCPT TO: &lt;<a href="mailto:gbush@whitehouse.gov">gbush@whitehouse.gov</a>&gt;
    and waits for a positive response.&nbsp; A negative response means the address is invalid
    or some other error, like mailbox is full.</li>
  <li>The client issue the DATA: command and waits for a positive response.</li>
  <li>The client begins to send the actual email message line by line, ending it with a
    &quot;.&quot; line.&nbsp; The client then waits for a positive response indicating the
    email was successfully received.</li>
  <li>The client issues the QUIT command and waits for a positive response.</li>
  <li>The client ends.</li>
</ol>

<p>In summary, the smtp client commands and smtp server responses occur:</p>
<div align="center"><center>

<table border="1" width="94%">
  <tr>
    <td width="44%" bgcolor="#C0C0C0" align="center">SMTP CLIENT COMMANDS</td>
    <td width="56%" bgcolor="#C0C0C0" align="center">SMTP SERVER RESPONSES</td>
  </tr>
  <tr>
    <td width="44%">&nbsp;</td>
    <td width="56%">220 Connected to Domain XXX,&nbsp; Server Ready!</td>
  </tr>
  <tr>
    <td width="44%">HELO or EHLO &lt;client domain name&gt;</td>
    <td width="56%">250 Hello Client Domain!</td>
  </tr>
  <tr>
    <td width="44%">MAIL FROM: &lt;your email address&gt;</td>
    <td width="56%">250 &lt;address&gt;.... Sender Ok!</td>
  </tr>
  <tr>
    <td width="44%">RCPT TO: &lt;<a href="mailto:gbush@whitehouse.gov">gbush@whitehouse.gov</a>&gt;</td>
    <td width="56%">250 &lt;address&gt;.... Receipient ok</td>
  </tr>
  <tr>
    <td width="44%">DATA</td>
    <td width="56%">354 Start mail input; end with &lt;CRLF&gt;.&lt;CRLF&gt;</td>
  </tr>
  <tr>
    <td width="44%">email message</td>
    <td width="56%">&nbsp;</td>
  </tr>
  <tr>
    <td width="44%">.</td>
    <td width="56%">250 Message received!</td>
  </tr>
  <tr>
    <td width="44%">QUIT</td>
    <td width="56%">221 Closing connection, Goodbye!</td>
  </tr>
</table>
</center></div>

<p>Please note how the SMTP server uses numeric response codes for server responses.
&nbsp; They control how the client will react.&nbsp; For example, when the client issues
the RCPT TO: command,&nbsp; the positive response code is 250 to indicate the address is
acceptable.&nbsp; However, negative response codes such as 550 can be issued which means
the &quot;unknown address.&quot;</p>

<p>The point behind this example is to illustrate the &quot;tight&quot; client/server
state machine conversation between a state-based protocol server and a state-based
protocol client such as in SMTP. Servers like SMTP have specific RFC design guidelines
that describe the proper state machine (commands and responses).&nbsp; The same is true
for FTP, NNTP and POP3.</p>

<p>With <code>CSPServer</code>, you can create your own client/server state machine
conversation.&nbsp; You can use a similar response code concept for your own for your
particular client/server application.</p>

<h2>Understanding the CSPServer State Machine</h2>

<p>The following figure 1.0 illustrates the &quot;state machine&quot; in <code>CSPServer</code>:</p>
<div align="center"><center>

<table border="0" width="83%">
  <tr>
    <td width="123%"
    style="border-left: medium none; border-right: medium none; border-top: medium solid; border-bottom: medium solid"
    colspan="3"><p align="center"><strong><font face="Courier New">Figure 1.0<big><br>
    </big>CSPServer State machine</font></strong></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" bgcolor="#FFFF00" style="border: medium solid" bordercolor="#000000"><p
    align="center"><strong><font face="Courier New">Server Applet<br>
    Client Connection Listening Thread</font></strong></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"><p
    align="center"><font face="Courier New" color="#FF0000">&lt;--connect--</font></td>
    <td width="56%" bgcolor="#C0C0C0" style="border: medium solid" bordercolor="#000000"><p
    align="center"><font face="Courier New">Client Applet</font></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"><p
    align="center">|<br>
    Accept<br>
    |</td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" bgcolor="#80FFFF" style="border: medium dashed" bordercolor="#000000"><p
    align="center"><font face="Courier New">Instantiate subclass CSPServer <br>
    Object thread</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%"></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"><p
    align="center"><font face="Courier New">|</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" style="border: medium dashed" bgcolor="#80FFFF" bordercolor="#000000"><p
    align="center"><font face="Courier New">Call subclass<br>
    Go() Handler</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"><p
    align="center"><font face="Courier New">|</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" style="border: medium solid"><p align="center"><font face="Courier New">call
    subclass SendWelcome()handler</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"
    valign="middle"><p align="center"><font face="Courier New" color="#FF0000">--response--&gt;</font></td>
    <td width="56%" valign="top" style="border: medium solid"><font face="Courier New">Client
    waits for welcome response</font></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" rowspan="2" style="border: medium solid"><p align="center"><font
    face="Courier New">Command1()handler</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"><p
    align="center"><font face="Courier New" color="#FF0000">&lt;-----------</font></td>
    <td width="56%" rowspan="2" valign="top" style="border: medium solid"><font
    face="Courier New">command1</font></td>
  </tr>
  <tr>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"
    valign="middle"><p align="center"><font face="Courier New" color="#FF0000">--response--&gt;</font></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%" rowspan="2" style="border: medium solid"><p align="center"><font
    face="Courier New">Command2()handler</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"><p
    align="center"><font face="Courier New" color="#FF0000">&lt;-----------</font></td>
    <td width="56%" rowspan="2" valign="top" style="border: medium solid"><font
    face="Courier New">command2</font></td>
  </tr>
  <tr>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"
    valign="middle"><p align="center"><font face="Courier New" color="#FF0000">--response--&gt;</font></td>
  </tr>
  <tr>
    <td width="38%" style="border-left: medium none; border-right: medium none"><p
    align="center"><font face="Courier New">.<br>
    .</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"><p
    align="center"><font face="Courier New">.<br>
    .</font></td>
  </tr>
  <tr>
    <td width="38%" rowspan="2" style="border: medium solid"><p align="center"><font
    face="Courier New">CommandN()handler</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"><p
    align="center"><font face="Courier New" color="#FF0000">&lt;-----------</font></td>
    <td width="56%" rowspan="2" valign="top" style="border: medium solid"><font
    face="Courier New">commandN</font></td>
  </tr>
  <tr>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"
    valign="middle"><p align="center"><font face="Courier New" color="#FF0000">--response--&gt;</font></td>
  </tr>
  <tr>
    <td width="38%"></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%"></td>
  </tr>
  <tr>
    <td width="38%" style="border: medium dashed" bgcolor="#80FFFF" bordercolor="#000000"><p
    align="center"><font face="Courier New">run optional subclass Cleanup()handler when client
    disconnects</font></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%" style="border-left: medium none; border-right: medium none"></td>
  </tr>
  <tr>
    <td width="38%"></td>
    <td width="29%" style="border-top: medium none; border-bottom: medium none"></td>
    <td width="56%"></td>
  </tr>
</table>
</center></div>

<p>When the client first connects , the listening server will start a new <code>CSPServer</code>
session which start a new thread to manage client session.&nbsp; The thread handler will
call the subclass Go() handler.<br>
<br>
The subclass Go() handler can be used to collect connection information but its main goal
is to start the state machine engine by calling the inherited Go() handler. </p>

<p>The inherited Go() handler will then call the virtual &quot;SendWelcome()&quot;
function and begin the state machine.&nbsp; The SendWelcome() override provides the
opportunity for the SPS to&nbsp; introduce itself&nbsp; and also possibly supply
&quot;readiness&quot; information to the client.</p>

<h2>Using the CSPServer Class</h2>

<p>For those who wish to get started quickly,&nbsp; the following is a &quot;quick how to
use&quot; outline.&nbsp; For technical class or code details see the source code and
examples provided.</p>

<p>At a minimum, to create a SPS using the <code>CSPServer</code> class, you need to do
following items (in no particular order): 

<ol>
  <li>Create a subclass of <code>CSPServer</code>, </li>
  <li>Override the subclass constructor, </li>
  <li>Override of the Go() handler in your subclass, </li>
  <li>Add a TSPDispatch member variable,</li>
  <li>Create a TSPDispatch structure defining the state machine dispatch commands,</li>
  <li>Add command dispatch handlers to the subclass, and</li>
  <li>Create a Listening Server Thread to answer incoming connections</li>
</ol>

<p>There are other virtual functions you can override, but the constructor and Go() are
the only required overrides to start the <code>CSPServer</code> engine.</p>

<p>The SampleServer.cpp source file contains a complete working example of a SPS. &nbsp;
The following are the basic steps in create an SPS:</p>

<p><u>Step 1:</u></p>

<p>Add #include &lt;spserver.h&gt; to your source code, and create a <code>CSPServer</code>
subclass (i.e., CMySPServer) such as the one shown below.&nbsp; </p>

<p>For the sake of an example, we will create a state machine with 5 commands; &nbsp;
&quot;HELLO&quot;, &quot;LOGIN&quot;, &quot;SHOW&quot;, &quot;HELP&quot; and
&quot;QUIT&quot;.&nbsp; So for each command a handler is added.</p>

<pre>#include &lt;spserver.h&gt;

class CMySPServer: public CSPServer {
    typedef CSPServer inherited;
public:
    CMySPServer(CSocketIO *s);  <font
color="#FF0000">// REQUIRED</font>
protected:
    virtual void Go(); <font color="#FF0000">// REQUIRED</font>
    virtual void SendWelcome();
private:
    static TSPDispatch Dispatch[]; <font
color="#FF0000">// REQUIRED</font>
    BOOL SPD_HELLO(char *args);
    BOOL SPD_LOGIN(char *args);
    BOOL SPD_SHOW(char *args);
    BOOL SPD_HELP(char *args);
    BOOL SPD_QUIT(char *args);
};
</pre>

<p>Please note the SendWelcome() override is optional.&nbsp; However, it is almost always
required to send a connection response to the client when the client first connects to the
server.&nbsp; </p>

<p>The class <code>CSocketIO</code> is a simple socket wrapper with formatting functions
and a socket input circular buffer.&nbsp; This class documentation is not within the scope
of this article.&nbsp; See the source file socketio.h/cpp for usage and reference.</p>

<p><u>Step 2:</u></p>

<p>Create the TSPDispatch structure for the subclass member Dispatch declaring the
commands and the commands dispatch handles as follows</p>

<pre>CSPServer::TSPDispatch CMySPServer::Dispatch[] = {
  SPCMD(CMySPServer, &quot;HELLO&quot;, SPD_HELLO),
  SPCMD(CMySPServer, &quot;LOGIN&quot;, SPD_LOGIN),
  SPCMD(CMySPServer, &quot;SHOW&quot;,  SPD_SHOW),
  SPCMD(CMySPServer, &quot;HELP&quot;,  SPD_HELP),
  SPCMD(CMySPServer, &quot;QUIT&quot;,  SPD_QUIT),
  {0}
};</pre>

<p>For each command in the Dispatch structure, declare a dispatch handler in the subclass
using the following prototype:</p>

<pre>BOOL dispatch_handler_name(char *args);</pre>

<p><font color="#0000FF">Advanced Usage: </font>It is possible to have an single handler
for call commands.&nbsp; In this case, you can use the method <code>GetCurrentCommandName()</code>
to return the current command issued.</p>

<p><u>Step 3:</u></p>

<p>Now begin to add the implementation of the overrides and the dispatch handlers:</p>

<pre>
<font color="#0000FF">//////////////////////////////////////////////////////////////
// Constructor
</font>
CMySPServer::CMySPServer(CSocketIO *s)
     : CSPServer(s, Dispatch)
{
    <font
color="#0000FF">// Initialize all your session variables here.

    // Done is a special BOOL used to exit
    // the inherited::Go() handler. One of the
    // Dispatch commands should set Done = TRUE;
    // i.e., QUIT() command.</font>

    Done = FALSE;

<font
color="#0000FF">    // start thread, calls Go() handler. If you
    // wish, you can call Start() outside the constructor.</font>

    Start();  
}

<font
color="#0000FF">//////////////////////////////////////////////////////////////
// Go() is called by start()</font>

void CMySPServer::Go()
{
    <font
color="#0000FF">// By this point, we have a new thread running. 
    // This is a good point to collect client ip or
    // domain information.

    // To start the state machine, you must call
    // the inherited Go() function.  This will
    // starts the thread's socket command line
    // reader and dispatcher. Go() returns when 
    // the Done is set TRUE or if connection drops
    // or one of the dispatch handlers return FALSE.
</font>
    inherited::Go(); <font
color="#FF0000">// REQUIRED</font>

   <font color="#0000FF"> // we are done, good place to do session
    // cleanup.
</font>
    delete this;  <font
color="#FF0000">// REQUIRED</font>
}

<font color="#0000FF">//////////////////////////////////////////////////////////////
// SendWelcome() is called by the inherited Go(). This is 
// a good place to provide &quot;server readiness&quot; information
// to the connecting client.  Standard SPS use numeric 
// response codes to provide this information. </font>

void CMySPServer::SendWelcome()
{
    Send(&quot;Hello! Server ready\r\n&quot;);
}

<font
color="#0000FF">//////////////////////////////////////////////////////////////
// <strong>Dispatch handlers. </strong> 
//
// Dispatch handlers have one parameter, char *args. It will 
// contain the string, if any, passed with the command. 
// 
// Return TRUE to continue the state machine. If FALSE is 
// returned, the session ends. <strong>NOTE: </strong>Returning FALSE is not 
// a good idea in practical designs as it can put the remote 
// client in a irregular state. You should always have a 
// graceful way to complete a session.  Even if you wish to 
// show &quot;error&quot; conditions, you should always return TRUE.
</font>
BOOL CMySPServer::SPD_HELLO(char *args)
{
    Send(&quot;--&gt; HELLO(%s)\r\n&quot;,args);
    return TRUE;
}

BOOL CMySPServer::SPD_LOGIN(char *args)
{
    Send(&quot;--&gt; LOGIN(%s)\r\n&quot;,args);
    return TRUE;
}

BOOL CMySPServer::SPD_SHOW(char *args)
{
    Send(&quot;--&gt; SHOW(%s)\r\n&quot;,args);
    return TRUE;
}

BOOL CMySPServer::SPD_HELP(char *args)
{
    Send(&quot;--- HELP commands ---\r\n&quot;);
    Send(&quot;HELLO\r\n&quot;);
    Send(&quot;LOGIN\r\n&quot;);
    Send(&quot;SHOW\r\n&quot;);
    Send(&quot;HELP\r\n&quot;);
    Send(&quot;QUIT\r\n&quot;);
    Send(&quot;--- end of help ---\r\n&quot;);
    return TRUE;
}

BOOL CMySPServer::SPD_QUIT(char *)
{
    Send(&quot;<click> Bye!\r\n&quot;);
    Control-&gt;Shutdown();   <font
color="#FF0000">// Disconnects socket</font>
    Done = TRUE;           <font
color="#FF0000">// Tells Go() to exit</font>
    return TRUE;
}
</pre>

<p>Step 4:</p>

<p>Finally, now that you have a <code>CSPServer</code> class ready, you need a listening
server thread that will answer incoming socket connections and for each new connection, a <code>CSPServer</code>
instance is started.&nbsp;</p>

<p>To create the Listening Server, the CThread class is used: </p>

<pre>class CServerThread : public CThread {
&nbsp;&nbsp;&nbsp; typedef CThread inherited;
public:
   CServerThread(const DWORD port = 4044, const DWORD flags = 0);
   virtual void Stop();
protected:
   virtual void Go();
private:
   SOCKET serverSock;
   DWORD serverPort;
};</pre>

<p>The subclass Go() handler is used to create the listening socket server.&nbsp; </p>

<p>When a new connection is accepted, a new instance of CMySPServer is created passing the
peer socket handle as a new&nbsp; <code>CSocketIO</code> object in the CMySPServer
constructor.&nbsp; The following is done in the CServerThread::Go() handler:</p>

<pre>  .
  .
  SOCKET t = accept(serverSock, (sockaddr *)&amp;src, &amp;x);
  if (serverSock == INVALID_SOCKET) break; <font
color="#FF0000">// listening server broken</font>
  new CMySPServer(new CSocketIO(t)); <font
color="#FF0000">      // Start new CMySPServer session
</font>  .
  .<font color="#FF0000"> </font></pre>

<p>You don't need to work about releasing the objects.&nbsp; The class themselves will do
the cleanup.</p>

<p>Example usage of CServerThread in a console application:</p>

<pre>  CServerThread server(4044);

  while (!Abort) {
    if (kbhit() &amp;&amp; getch() == 27) break;  <font
color="#FF0000">// Escape to Exit</font>
    Sleep(30);
  }

  server.Stop();</pre>

<h2>Points of Interest</h2>

<p>See the source file SampleServer.cpp for a complete working example.&nbsp; By default,
the example uses port 4044.&nbsp;&nbsp; To test the server, use telnet like so:</p>

<p>&nbsp;&nbsp;&nbsp; Telnet LocalHost 4044</p>

<h2>History</h2>

<p>v1.0P - March 4, 2003, Initial Public Release</p>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions