WCF and gSOAP client & server examples
======================================
Overview
--------
This example demonstrates how to implement a SOAP/XML calculator web service client and server application in C++ that communicates with a WCF C# client and server application.
This article describes the use of two machines for software development: the Windows machine with the WCF C# client and service and the "other" machine with the gSOAP C++ client and service. However, the "other" machine may just be the same machine as the Windows machine. To distinguish the commands executed on the Windows WCF C# side using the Windows command prompt utility from the "other" side:
[command]
C:> denotes the Windows's machine command line for WCF C#
$ denotes the "other" machine command line for gSOAP C++
[![To top](../../images/go-up.png) To top](#)
Downloading the WCF C# samples
------------------------------
Download and install the Microsoft Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) [Samples for .NET Framework 4.](https://www.microsoft.com/en-us/download/details.aspx?id=21459)
After downloading and installing, you should have the following directory with the WCF Basic HTTP C# client and service projects:
[command]
C:\WF_WCF_Samples\WCF\Basic\Binding\Basic\Http\CS
Open the `Http.sln` solution file located in that directory in Visual Studio. The **Solution Explorer** panel should show the Http WCF C# example client and service project. If the **Solution Explorer** shows "Project unloaded" or "unavailable" then right-click the client project name in the **Solution Explorer** panel and select **Reload project**. Repeat for the service.
[![To top](../../images/go-up.png) To top](#)
Hosting the WCF service
-----------------------
WCF service applications can be [hosted with IIS or self-hosted.](https://msdn.microsoft.com/en-us/library/bb332338.aspx)
To build a self-hosted WCF C# service application, add a `Program` class with `static void Main()` to the `Microsoft.Samples.Http` namespace in the `service.cs` source of the service project. Also extend the list of modules used:
using System;
using System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Description;
namespace Microsoft.Samples.Http
{
... // do not modify this part of the source code that came with the example
public class Program
{
public static void Main()
{
Uri httpUrl = new Uri("http://10.0.1.5:8000/ServiceModelSamples/service");
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), httpUrl))
{
BasicHttpBinding bhb = new BasicHttpBinding();
serviceHost.AddServiceEndpoint(typeof(ICalculator), bhb, "");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
serviceHost.Description.Behaviors.Add(smb);
serviceHost.Open();
Console.WriteLine("Press to terminate service.");
Console.ReadLine();
}
}
}
The host IP and port of the service are set to 10.0.1.5:8000, but we should use the actual machine IP that you can find with the `ipconfig` command:
[command]
C:> ipconfig /all
Look for the IPv4 address. You can change the port number in `service.cs` to an available port.
Under **Project Properties** change the **Output type** to **Console Application**. Then build the project.
WCF self-hosting settings must be configured for HTTP, see the Microsoft WCF documentation on [Configuring HTTP and HTTPS.](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/configuring-http-and-https) For example, on Windows 7, 8 and 10 you need to add a URL reservation for the specified URL namespace for your account (change the port to the port you are using):
[command]
C:> netsh http add urlacl url=http://+:8000/ServerModelSamples/service user=YourUserName
This may require administrator privileges: right click the **Command Prompt** application icon on your desktop and select **Run as Administrator** and then execute the command shown above.
Next, run `service.exe` from the command prompt:
[command]
C:\WF_WCF_Samples\WCF\Basic\Binding\Basic\Http\CS\service\bin\service.exe
Use a web browser on this Windows machine to access the self-hosted WCF service at the service endpoint URL specified `http://10.0.1.5:8000/ServiceModelSamples/service` (remember to replace 10.0.1.5 with the IP address returned by `ipconfig`). This shows the service properties in your browser.
To view the WSDL, open the location `http://10.0.1.5:8000/ServiceModelSamples/service?wsdl` in your browser.
Using a browser from a remote machine on your private LAN to view the WCF service properties is a good way to verify if the service can be reached. If it fails, then change the firewall settings on the machine on which the self-hosted service runs to allow connections on port 8000 as follows.
To allow connections on port 8000 add a firewall rule:
[command]
C:> netsh advfirewall firewall add rule name="WCF service example" dir=in action=allow protocol=TCP localport=8000
To remove the firewall rule later:
[command]
C:> netsh advfirewall firewall delete rule name="WCF service example" dir=in action=allow protocol=TCP localport=8000
Uncheck "Block all incomming connections, including those in the list of allowed apps" in the "Public network settings" of Window's firewall.
If that fails, then IIS Express may not accept remote connections by default. In the Visual Studio 2015 **Solution Explorer** panel, right click the your project and click **Properties** then in the left tab, click **Web**. Select **IIS Express** with the Project URL and create a virtual directory. Make sure IIS Express is installed.
Configure IIS Express to accept remote connections by adding or editing the configuration file for IIS Express at `\.vs\config\applicationhost.config`:
[xml]
You will find lots of information on public forums and videos on the Web to help you get IIS express working to host your WCF service.
[![To top](../../images/go-up.png) To top](#)
Implementing a gSOAP client for the WCF service
-----------------------------------------------
Creating a gSOAP client for a WCF service is very easy. Once the WCF service runs, use the gSOAP wsdl2h tool from the command prompt to generate C++ source code for the client application from a single WSDL document:
[command]
$ wsdl2h -t typemap.dat -o calculator.h 'http://10.0.1.5:8000/ServiceModelSamples/service?singleWsdl'
Again, use the proper IP returned by `ipconfig` instead of 10.0.1.5.
You can find the `typemap.dat` file that is used by wsdl2h in the `gsoap-2.8/gsoap` directory of the gSOAP distribution. This file binds XML namespace prefixes such as `mssamh` to XML namespace URIs. It also defines common data types that WCF uses. We will use this XML namespace prefix `mssamh` in our client source code:
[command]
# typemap.dat XML namespace bindings and XSD type mappings
mssamh = "http://Microsoft.Samples.Http"
# .NET WCF DataContract Serialization Schema
ser =
arr = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"
# .NET WCF DataContract Serialization Schema root element remappings
_ser__anyURI == xsd__anyURI
... etc.
Note: `prefix = ` are built-in schemas, meaning that these are never downloaded by wsdl2h as all its types are (re)defined in the `typemap.dat` file, while `prefix = "URI"` binds the prefix and downloads the schema references in the WSDL or XSD files.
There is another service endpoint URL that you can use to obtain the WSDL and XSD documents, which are downloaded separately:
[command]
$ wsdl2h -t typemap.dat -o calculator.h 'http://10.0.1.5:8000/ServiceModelSamples/service?wsdl'
However, because the service is self-hosted this may take some time. A self-hosted service is a simple iterative web server that allows only one open connection at a time, while multiple connections are opened to access all files (WSDL and XSD files).
The wsdl2h tool generates [`calculator.h`](calculator.h) in the current directory. This file contains the service definitions and XML data bindings for C++ (or you can generate C with wsdl2h option -c).
The next step is to run soapcpp2 on [`calculator.h`](calculator.h) to generate the binding implementation source code:
[command]
$ soapcpp2 -Igsoap-2.8/gsoap/import -j -r -CL calculator.h
where option `-I` specifies the path to the `gsoap/import` directory in the gSOAP distribution package (change this as needed), option `-j` generates a C++ proxy class, option `-r` generates a report, and option `-CL` generates the client side only without (the unused) lib files.
This generates several files, including:
* [`soapStub.h`](soapStub.h) a copy of the specification in plain C/C++ header file syntax without annotations.
* [`soapH.h`](soapH.h) declares XML serializers.
* [`soapC.cpp`](soapC.cpp) implements XML serializers.
* [`soapBasicHttpBinding_USCOREICalculatorProxy.h`](soapBasicHttpBinding_USCOREICalculatorProxy.h) defines the client-side XML services API class `BasicHttpBinding_USCOREICalculatorProxy`.
* [`soapBasicHttpBinding_USCOREICalculatorProxy.cpp`](soapBasicHttpBinding_USCOREICalculatorProxy.cpp) implements the client-side XML services API class `BasicHttpBinding_USCOREICalculatorProxy`.
* [`BasicHttpBinding_USCOREICalculator.nsmap`](BasicHttpBinding_USCOREICalculator.nsmap) XML namespace binding table to #include
* [`soapReadme.md`](soapReadme.html) service and data binding interface details.
The `BasicHttpBinding_USCOREICalculatorProxy` class has four service methods:
* `int Add(_mssamh__Add *mssamh__Add, _mssamh__AddResponse *mssamh__AddResponse)`
* `int Subtract(_mssamh__Subtract *mssamh__Subtract, _mssamh__SubtractResponse *mssamh__SubtractResponse)`
* `int Multiply(_mssamh__Multiply *mssamh__Multiply, _mssamh__MultiplyResponse *mssamh__MultiplyResponse)`
* `int Divide(_mssamh__Divide *mssamh__Divide, _mssamh__DivideResponse *mssamh__DivideResponse)`
The `_mssamh__Add` request and `mssamh__AddResponse` response classes are declared in [`calculator.h`](calculator.h) (and also in the generated [`soapStub.h`](soapStub.h)) and can be conveniently browsed in the generated [`soapReadme.md`](soapReadme.html) report, as:
class _mssamh__Add
{ public:
double* n1 0;
double* n2 0;
struct soap *soap;
};
class _mssamh__AddResponse
{ public:
double* AddResult 0;
struct soap *soap;
};
where the annotation `0` next to `n1` and `n2` indicates that these are optional, as per gSOAP data binding interface notation, see [XML data bindings](https://www.genivia.com/doc/databinding/html/index.html) for details. Why this WCF service uses optional `n1` and `n2` parameters for the calculator is unclear (i.e. `minOccurs="0"`, but required elements in this example makes more sense and is also the XSD schema default for elements). The `soap` member points to the context that manages this instance when allocated on the managed heap, i.e. when objects are deserialized or constructed with `soap_new__mssamh__Add(soap)` and `soap_new__mssamh__AddResponse(soap)`, where `soap` is the managing context that is part of a proxy or service object, i.e. `proxy.soap` and `service.soap`, respectively. The same applies to the other classes used by the other three service methods.
To invoke a service method, instantiate the proxy class and invoke a proxy class method, for example as the client part [`calculator.cpp`](calculator.cpp) which is basically:
#include "soapBasicHttpBinding_USCOREICalculatorProxy.h"
#include "BasicHttpBinding_USCOREICalculator.nsmap"
int main()
{
const char *URI = "http://10.0.1.5:8000/ServiceModelSamples/service"; // the service endpoint
BasicHttpBinding_USCOREICalculatorProxy proxy(URI, SOAP_XML_INDENT);
proxy.soap->send_timeout = proxy.soap->recv_timeout = 10; // 10 sec timeouts
double n1 = 3.14, n2 = 1.41;
_mssamh__Add areq;
_mssamh__AddResponse ares;
areq.n1 = &n1;
areq.n2 = &n2;
if (proxy.Add(&areq, &ares) == SOAP_OK && ares.AddResult)
std::cout << "Add(" << n1 << ", " << n2 << ") = " << *ares.AddResult << std::endl;
else
proxy.soap_stream_fault(std::cerr);
proxy.destroy();
}
To build the example client application from its source code [`calculator.cpp`](calculator.cpp) we also need `stdsoap2.h` and `stdsoap2.cpp` to compile:
[command]
$ c++ -o calculator calculator.cpp stdsoap2.cpp soapC.cpp soapBasicHttpBinding_USCOREICalculatorProxy.cpp
Then run:
[command]
$ ./calculator
Add(3.14, 1.41) = 4.55
Subtract(3.14, 1.41) = 1.73
Multiply(3.14, 1.41) = 4.4274
Divide(3.14, 1.41) = 2.22695
[![To top](../../images/go-up.png) To top](#)
Implementing a gSOAP service for the WCF client
-----------------------------------------------
Implementing a gSOAP service is arguably very easy compared to the WCF C# service and the configuration settings for IIS.
The gSOAP service part of [`calculator.cpp`](calculator.cpp) is basically:
#include "soapBasicHttpBinding_USCOREICalculatorService.h"
#include "BasicHttpBinding_USCOREICalculator.nsmap"
int main(int argc, char **argv)
{
if (argc >= 2)
{
int port = atoi(argv[1]);
BasicHttpBinding_USCOREICalculatorService service(SOAP_XML_INDENT);
service.soap->send_timeout = service.soap->recv_timeout = 5; // 5 sec socket idle timeout
service.soap->transfer_timeout = 30; // 30 sec message transfer timeout
std::cerr << "Server running" << std::endl;
while (service.run(port))
service.soap_stream_fault(std::cerr);
}
}
and the service class has four service operations implemented as follows:
int BasicHttpBinding_USCOREICalculatorService::Add(_mssamh__Add *Add, _mssamh__AddResponse *AddResponse)
{
double *res = (double*)soap_malloc(soap, sizeof(double));
if (Add && Add->n1 && Add->n2)
*res = *Add->n1 + *Add->n2;
else
return soap_sender_fault(soap, "Invalid data", NULL);
AddResponse->AddResult = res;
return SOAP_OK;
}
int BasicHttpBinding_USCOREICalculatorService::Subtract(_mssamh__Subtract *Subtract, _mssamh__SubtractResponse *SubtractResponse)
{
double *res = (double*)soap_malloc(soap, sizeof(double));
if (Subtract && Subtract->n1 && Subtract->n2)
*res = *Subtract->n1 - *Subtract->n2;
else
return soap_sender_fault(soap, "Invalid data", NULL);
SubtractResponse->SubtractResult = res;
return SOAP_OK;
}
int BasicHttpBinding_USCOREICalculatorService::Multiply(_mssamh__Multiply *Multiply, _mssamh__MultiplyResponse *MultiplyResponse)
{
double *res = (double*)soap_malloc(soap, sizeof(double));
if (Multiply && Multiply->n1 && Multiply->n2)
*res = *Multiply->n1 * *Multiply->n2;
else
return soap_sender_fault(soap, "Invalid data", NULL);
MultiplyResponse->MultiplyResult = res;
return SOAP_OK;
}
int BasicHttpBinding_USCOREICalculatorService::Divide(_mssamh__Divide *Divide, _mssamh__DivideResponse *DivideResponse)
{
double *res = (double*)soap_malloc(soap, sizeof(double));
if (Divide && Divide->n1 && Divide->n2 && *Divide->n2 != 0.0)
*res = *Divide->n1 / *Divide->n2;
else
return soap_sender_fault(soap, "Invalid data", NULL);
DivideResponse->DivideResult = res;
return SOAP_OK;
}
The next step is to run soapcpp2 on [`calculator.h`](calculator.h) to generate the binding implementation source code:
[command]
$ soapcpp2 -Igsoap-2.8/gsoap/import -j -r -SL calculator.h
where option `-I` specifies the path to the `gsoap/import` directory in the gSOAP distribution package (change this as needed), option `-j` generates a C++ service class, option `-r` generates a report, and option `-SL` generates the server side only without (the unused) lib files.
This generates several files, including:
* [`soapStub.h`](soapStub.h) a copy of the specification in plain C/C++ header file syntax without annotations.
* [`soapH.h`](soapH.h) declares XML serializers.
* [`soapC.cpp`](soapC.cpp) implements XML serializers.
* [`soapBasicHttpBinding_USCOREICalculatorService.h`](soapBasicHttpBinding_USCOREICalculatorService.h) defines the server-side XML services API class `BasicHttpBinding_USCOREICalculatorService`.
* [`soapBasicHttpBinding_USCOREICalculatorService.cpp`](soapBasicHttpBinding_USCOREICalculatorService.cpp) implements the server-side XML services API class `BasicHttpBinding_USCOREICalculatorService`.
* [`BasicHttpBinding_USCOREICalculator.nsmap`](BasicHttpBinding_USCOREICalculator.nsmap) XML namespace binding table to #include
* [`soapReadme.md`](soapReadme.html) service and data binding interface details.
To build the example service application from its source [`calculator.cpp`](calculator.cpp) we also need `stdsoap2.h` and `stdsoap2.cpp` to compile:
[command]
$ c++ -o calculator calculator.cpp stdsoap2.cpp soapC.cpp soapBasicHttpBinding_USCOREICalculatorService.cpp
Then run:
[command]
$ ./calculator 8000
[![To top](../../images/go-up.png) To top](#)
Running the WCF client
----------------------
First we need to set the service endpoint in `App.config` of the example WCF client in **Solution Explorer**, which is the host name or IP and port of the machine on which the gSOAP server runs. Say for example the server endpoint is "10.0.1.5" on port 8000:
[xml]
If you run the server on the same machine as the client, then you can use:
[xml]
Under **Project Properties** of the example WCF client, change the **Output type** to **Console Application**. After compiling the WCF client in Visual Studio, run the WCF client:
[command]
C:> WF_WCF_Samples\WCF\Basic\Binding\Basic\Http\CS\client\bin\client.exe
When the gSOAP server runs remotely and the client cannot connect to the machine on which the server runs then check your firewall settings on both machines to permit TCP connections on the server port.
[![To top](../../images/go-up.png) To top](#)
Hosting the WCF service with HTTPS transport security
-----------------------------------------------------
To set up the WCF service, navigate to the following directory:
[command]
C:\WF_WCF_Samples\WCF\Basic\Binding\Basic\TransportSecurity\CS
Open the `TransportSecurity.sln` solution file located in that directory in Visual Studio. The **Solution Explorer** panel should show the TransportSecurity WCF C# example client and service project. If the **Solution Explorer** shows "Project unloaded" or "unavailable" then right-click the client project name in the **Solution Explorer** panel and select **Reload project**. Repeat for the service.
To build a self-hosted WCF C# service application, add a `Program` class with `static void Main()` to the `Microsoft.Samples.TransportSecurity` namespace in the `service.cs` source of the service project. Also extend the list of modules used:
using System;
using System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Description;
namespace Microsoft.Samples.TransportSecurity
{
... // do not modify this part of the source code that came with the example
public class Program
{
public static void Main()
{
Uri httpUrl = new Uri("https://10.0.1.5:8000/ServiceModelSamples/service");
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), httpUrl))
{
BasicHttpBinding bhb = new BasicHttpBinding();
bhb.Security.Mode = BasicHttpSecurityMode.Transport;
bhb.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
serviceHost.AddServiceEndpoint(typeof(ICalculator), bhb, "");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpsGetEnabled = true;
serviceHost.Description.Behaviors.Add(smb);
serviceHost.Open();
Console.WriteLine("Press to terminate service.");
Console.ReadLine();
}
}
}
}
The host IP and port of the service are set to 10.0.1.5:8000, but we should use the actual machine IP and you can change the port number to an available port.
Under **Project Properties** change the **Output type** to **Console Application**. Then build the project.
WCF self-hosting settings must be configured for HTTPS, see the Microsoft WCF documentation on [Configuring HTTP and HTTPS.](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/configuring-http-and-https) For example, on Windows 7, 8 and 10 you need to add a URL reservation for the specified URL namespace for your account (change the port to the port you are using):
[command]
C:> netsh http add urlacl url=https://+:8000/ServerModelSamples/service user=YourUserName
This may require administrator privileges: right click the **Command Prompt** application icon on your desktop and select **Run as Administrator** and then execute the command shown above.
You must [configure a port with an SSL certificate](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate) for the self-hosted service to work properly. If you are using IIS then [configure an IIS-hosted WCF service with SSL.](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl)
Next, run `service.exe` from the command prompt:
[command]
C:\WF_WCF_Samples\WCF\Basic\Binding\Basic\TransportSecurity\CS\service\bin\service.exe
Use a web browser on this Windows machine to access the self-hosted WCF service at the service endpoint URL specified `https://10.0.1.5:8000/ServiceModelSamples/service` (remember to replace 10.0.1.5 with the IP address returned by `ipconfig`). This shows the service properties in your browser. The browser will probably complain that the URL is not secure.
[![To top](../../images/go-up.png) To top](#)
Implementing a gSOAP client for the HTTPS WCF service
-----------------------------------------------------
To set up the gSOAP client for the WCF service we do not need to generate code with wsdl2h and soapcpp2 again, since the steps as the same as for the Basic Http example. Simply change the [`calculator_https.cpp`](calculator_https.cpp) source to use the HTTPS URL:
const char *URI = "https://10.0.1.5:8000/ServiceModelSamples/service";
Optionally, add the following code after constructing the proxy object to configure the validation of the server credentials by setting the `soap_ssl_client_context` options to verify the server using the certificate [`cacert.pem`](cacert.pem):
BasicHttpBinding_USCOREICalculatorProxy proxy(URI, SOAP_XML_INDENT);
if (soap_ssl_client_context(proxy.soap,
SOAP_SSL_DEFAULT | SOAP_SSL_SKIP_HOST_CHECK,
NULL,
NULL,
"cacert.pem",
NULL,
NULL))
{
proxy.soap_stream_fault(std::cerr);
exit(1);
}
See the [tutorials](https://www.genivia.com/tutorials.html) for more details on how to configure HTTPS and to ensure OpenSSL thread safety.
[![To top](../../images/go-up.png) To top](#)
Implementing a HTTPS gSOAP service for the WCF client
-----------------------------------------------------
The gSOAP service part of [`calculator_https.cpp`](calculator_https.cpp) is the same as before, but we should invoke `ssl_run(port)` instead of `run(port)`:
#include "soapBasicHttpBinding_USCOREICalculatorService.h"
#include "BasicHttpBinding_USCOREICalculator.nsmap"
int main(int argc, char **argv)
{
if (argc >= 2)
{
int port = atoi(argv[1]);
BasicHttpBinding_USCOREICalculatorService service(SOAP_XML_INDENT);
if (soap_ssl_server_context(service.soap,
SOAP_SSL_DEFAULT,
"server.pem",
"password",
"cacert.pem",
NULL,
NULL,
NULL,
NULL))
{
service.soap_stream_fault(std::cerr);
exit(1);
}
service.soap->send_timeout = service.soap->recv_timeout = 5; // 5 sec socket idle timeout
service.soap->transfer_timeout = 30; // 30 sec message transfer timeout
std::cerr << "Server running" << std::endl;
while (service.ssl_run(port))
service.soap_stream_fault(std::cerr);
}
}
Two PEM files are required for HTTPS services with OpenSSL:
* [`cacert.pem`](cacert.pem) contains the X509 certificate (this example is a self-signed certificate), which should be shared with client applications.
* [`server.pem`](server.pem) contains the private key, which should never be shared and kept safe. The private key file may be encrypted with a password (the "password" for this example) that is needed to unlock this file in `soap_ssl_server_context`.
See the [tutorials](https://www.genivia.com/tutorials.html) for more details on how to configure HTTPS services and to ensure OpenSSL thread safety.
The source code files that we need are generated in the previous steps with:
[command]
$ soapcpp2 -Igsoap-2.8/gsoap/import -j -r -SL calculator.h
We can now build the example service application from its source [`calculator_https.cpp`](calculator_https.cpp). To compile, we also need `stdsoap2.h` and `stdsoap2.cpp` and link with OpenSSL:
[command]
$ c++ -DWITH_OPENSSL -o calculator_https calculator_https.cpp stdsoap2.cpp soapC.cpp soapBasicHttpBinding_USCOREICalculatorService.cpp -lssl -lcrypto
The `-DWITH_OPENSSL` option is important to enable OpenSSL in the gSOAP engine.
Then run:
[command]
$ ./calculator_https 8000
[![To top](../../images/go-up.png) To top](#)
Running the HTTPS WCF client
----------------------------
We need to convert the [`cacert.pem`](cacert.pem) file with the X509 certificate in PEM format to DER format [`cacert.cer`](cacert.cer) for the WCF client:
[command]
$ openssl x509 -in cacert.pem -outform der -out cacert.cer
Import [`cacert.cer`](cacert.cer) by opening this file on the Windows machine and then select **Install Certificate**.
Change `client.cs` by removing the `RemoteCertValidate()` check by letting this function always return true, or modify according to certificate properties that you want to be enforced.
To connect to the gSOAP service, edit the service endpoint in `App.config` of the example WCF client in **Solution Explorer**, which is the host name or IP and port of the machine on which the gSOAP server runs. Say for example the server endpoint is "10.0.1.5" on port 8000:
[xml]
If you run the server on the same machine as the client, then you can use:
[xml]
Under **Project Properties** of the example WCF client, change the **Output type** to **Console Application**. After compiling the WCF client in Visual Studio, run the WCF client:
[command]
C:> WF_WCF_Samples\WCF\Basic\Binding\Basic\TransportSecurity\CS\client\bin\client.exe
When the gSOAP server runs remotely and the client cannot connect to the machine on which the server runs then check your firewall settings on both machines to permit TCP connections on the server port.
[![To top](../../images/go-up.png) To top](#)
Readme report
-------------
See the auto-generated [soapReadme](soapReadme.html) for this example.
[![To top](../../images/go-up.png) To top](#)
Additional information
----------------------
The gSOAP distribution package includes these and other WCF example applications that cover transport security (HTTPS), message security (WS-Security), and reliable messaging (WS-ReliableMessaging).
[![To top](../../images/go-up.png) To top](#)