Skip to main content
Visual C++ Samples 
SOAPTransport Sample: Communicates SOAP Messages Over Sockets, MSMQ, the File System, and HTTP Listener 

Download sample

Demonstrates the creation of SOAP servers and clients that communicate using different transports: sockets, Microsoft Message Queue, the file system, and a custom HTTP listener.

The SOAPTransport sample consists of eight projects: a SOAP server and a client for each of the four supported transports.

The sample shows how to separate the SOAP support offered by ATL Server from the ISAPI framework, allowing use of ATL Server to build SOAP servers and clients over virtually any communication channel.

Security noteSecurity Note

This sample code is provided to illustrate a concept and should not be used in applications or Web sites, as it may not illustrate the safest coding practices. Microsoft assumes no liability for incidental or consequential damages should the sample code be used for purposes other than as intended.


  • MSMQ

Building and Running the Sample

To build and run this sample

  1. Open the solution file, SoapTransport.sln, in the Visual Studio development environment.

  2. Build the solution.


    This will build all the client and server applications.

  3. Run FloppyTransport:

    1. Start the FloppyClient application. It will ask for the name of the file to save the request to. Enter a file name.

    2. Start the FloppyServer application. It will ask for the file containing the request. Enter the file where the request was saved.

    3. The server application will ask for a file to save the response to. Enter a file name.

    4. Return to the FloppyClient running instance and press any key. It will ask for the file containing the response. Enter the file where the server saved the SOAP response.

      The result of the SOAP invocation is displayed.

  4. Run TCPIPTransport:

    1. Start the TCPServer application. It will launch the TCP/IP listener.

    2. Start the TCPClient application. It will send the request and then display the result of the invocation.

  5. Run MSMQTransport (you will need the Message Queuing Services installed on your computer):

    1. Start the MQServer application. It will create a message queue and wait for a message containing a SOAP request to be posted.

    2. Start the MQClient application. It will post the request and then display the result of the invocation.

  6. Run HTTPListenerTransport:

    1. Start the HTTPListenerServer application. It will wait for a message containing a SOAP request to be posted.

    2. Start the HTTPListenerCSharpClient application. It will send the request and then display the result of the invocation.

How the Sample Works

The following discussion covers the server, client, and transports.

Server Side

The ATL Server Web Service application wizard will generate the code for an XML Web service exposed through HTTP. The XML Web service is implemented as a class with the following declaration:

request_handler(name="Default", sdl="GenSimpleSoapAppServiceWSDL"),
class CSimpleSoapAppService :
   public ISimpleSoapAppService

In this code sequence, the attributes before the class declaration do most of the work. The soap_handler attribute will make the class a CSoapHandler<CSimpleSoapAppService> derivative (that is, an XML Web service) able to handle SOAP messages and map them to internal method calls, and also to wrap the result of internal method invocations to SOAP responses. The request_handler attribute will make it able to handle HTTP requests.

If the transport layer is not going to be HTTP, the request_handler attribute is no longer needed, so it can be commented out.

The CSoapHandler<> class in atlsoap.h is designed to handle SOAP requests through HTTP. The entry point for handling an HTTP SOAP request is:

HTTP_CODE HandleRequest(AtlServerRequest *, IServiceProvider *)

The request body and the SOAP-related HTTP header ("SOAPAction") are retrieved from the ISAPI extension through the pServerRequest (an ECB wrapper) member of the AtlServerRequest* parameter.

The pServerRequest object provides methods for reading the request body, reading the SOAPAction HTTP header, and writing the SOAP response back to the client. As this sample intends to replace the HTTP transport, it needs to launch the SOAP request processing and to provide it with a way of performing the same operations.

This is solved by creating a CSoapHandler derivative, CSoapTransportHandler, that implements the following entry point (in file SoapTransportSrv.h of the sample):

HTTP_CODE InvokeSoapMethod(stSoapTransportDescription   *pTransInfo) 

The stSoapTransportDescription is defined as:

struct  stSoapTransportDescription
// the stream to write the SOAP response to
   IWriteStream   *pWriteStream;   
// the stream to read the SOAP request from
   IStream      *pReadStream;
// the SOAP Action   
CStringA         strSOAPAction;    
// the service provider
   IServiceProvider   *pServiceProvider; 

Perhaps the only member that needs explanation is pServiceProvider. It allows the SOAP servers to share services exactly as those in an ISAPI DLL. It can be NULL in an implementation, as long as the SOAP servers will not attempt to use it. One of the services commonly exposed through the service provider is the MSXML Reader.

Now, the SOAP server class generated by the wizard has to be modified to use the new CSoapTransportHandler functionality. The new code would look like this:

      // request_handler(name="Default", sdl= "GenSimpleSoapAppWSDL"),
class CSimpleSoapAppService :
   public CSoapTransportHandler<CSimpleSoapAppService>,
   public ISimpleSoapAppService

No other modifications need to be done in the server code.

At this point, the SOAP server can be instantiated and the SOAP methods can be invoked through CSoapTransportHandler::InvokeSoapMethod. Using custom read and write streams, there is no longer a dependency on ATL Server HTTP support.

The instantiation of the server or servers is handled by another class, CSoapDispatcher, implemented in the soapDispatch.h file of the sample.

At this point, a server application only has to:

  • Get the SOAP request and the SOAP Action header through any transport channel.

  • Wrap the request in an IStream interface.

  • Provide a stream to store the response.

  • Invoke CSoapDispatcher::DispatchCall.

  • Send the content of the write stream (the SOAP response) over any transport channel to the client.

Client Side

The template-based code generated by the sproxy.exe tool for an ATL Server SOAP client makes for easy overriding of the transport on the client side. The SOAP proxy class generated by sproxy.exe has the following prototype:

template <typename TClient = CSoapSocketClientT<> >
class CSimpleSoapAppServiceT 

The methods that have to be implemented by the TClient template parameter are well documented in the ATL Server Reference. The method that is really of importance here is SendRequest. That method is supposed to send the request from a stream to the SOAP server and to fill a different stream with the server response.

With a custom class that contains all of the methods required to be a TClient, the actual channel used to send the request to the SOAP server only affects the implementation of the SendRequest method.

Transport Channels

The sample implements the following transport channels:

  • TCP/IP communication

  • MSMQ communication

  • Communication through files

Each transport channel implementation contains a client application and a server application. The server uses the SOAP server included in the "Include" folder (which is built as described above). The code in the server application only takes care of the transport. The client application only implements the transport-specific class to act as a TClient parameter for the Sproxy.exe-generated class.

A limitation of the sample is that the WSDL used in generating the proxy has to be generated outside of the sample. The WSDL used in the applications specified above is saved as simpleSoapSrv.wsdl in the "Include" folder. The solution for this would be to create the SOAP server through the wizard, complete the interface and then save the WSDL through the default HTTP way provided by ATL Server.

An Extension: HTTPListenerTransport

This folder contains an enhanced version of the TCPIPTransport server. This server listens on a specified TCPIP port, but it accepts HTTP requests. It provides a way of responding to .disco requests, to generate the WSDL for the implemented SOAP servers and also to accept SOAP invocations. This server can provide a very lightweight, complete, SOAP implementation without requiring an HTTP server to be installed on the computer.

To create a client for this lightweight server, use the Add Web Reference wizard from the Visual Studio IDE and point the wizard to the following URL:


The client provided for this server (HttpListenerCSharpClient) is generated this way.


See Also