Introduction
In this document, I want to explain how to call any web service from any programming language C, C++, C#, Java … and so on.
Using this article, you can also call the web services using handheld or mobile or any terminal that supports TCP/IP protocol.
As we know, we can call web service in C# adding web reference to a project and call the functions of the web service.
If you want to know how, you can Google it and you will find a lot of pages that describe how to do this.
For programmers that need to connect to a web service using C language, they can use any of the SOAP libraries to call the web service. For me, I used GSOAP
library. It is good enough to be used in this method.
But here, we do not want to add web reference and we do not want to use any external library.
We want to call the web service using three things, server IP, server PORT, data that has our request and also receive data for response.
1-Server IP
Our server here is the server that has the web service. In my example, I used a free web service http://www.webservicex.net/globalweather.asmx so my server is http://www.webservicex.net/ and its IP is 173.201.44.188.
2- Server PORT
Now, which port will I choose to send my request to? Actually, you have only one choice here.
Because my call will be as HTTP POST as we will see, we will use the default HTTP port for this to call any web service. This port is 80.
3- Data
The final thing we want to determine to finish our method is the data I will send. Fortunately, it is in our hands. Open my web service example http://www.webservicex.net/globalweather.asmx and choose GetCitiesByCountry
function.
This will be the page that will be opened to you http://www.webservicex.net/globalweather.asmx?op=GetCitiesByCountry. You can now see a place to enter the country you want to get its cities and there are some HTTP request/response codes in the page.
We will take the HTTP request under SOAP 1.1.
POST /globalweather.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.webserviceX.NET/GetCitiesByCountry"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetCitiesByCountry xmlns="http://www.webserviceX.NET">
<CountryName>string</CountryName>
</GetCitiesByCountry>
</soap:Body>
</soap:Envelope>
This will be the XML request that we will send to the server.
At the beginning of the XML request, we can see that the HTTP method is POST
and determine some parameters to the call, in Body
it determines the function I want to call.
In this code, we will replace word string by the country we want to get its cities like Egypt and we will replace length by how many bytes this request has? (count them:-p)
After sending this data to the server, we will get a XML response like this:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
="1.0"="utf-8"
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetCitiesByCountryResponse xmlns="http://www.webserviceX.NET">
<GetCitiesByCountryResult>string</GetCitiesByCountryResult>
</GetCitiesByCountryResponse>
</soap:Body>
</soap:Envelope>
but replacing the string
with all the returned responses from the web service depending on the function we have called.
Now from any terminal that can send and receive data using TCP/IP protocol, you have IP, Port, data. Send the data to the IP and Port and you can receive the response.
The Code
Here I used C# to make a simple test for my words, I used it because it is very easy for understanding but you can use any other language.
At first, we use System.Net
and System.Net.Sockets
to can use TCP functions.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
I used System.IO
because I will save my request and response on files so I want read and write operations on files.
I created a TCP client and connect it to the server IP and port 80 as I said before:
TcpClient myclient = new TcpClient();
My request is on a txt file called data.txt. I opened it and filled the request from it to array of bytes. You can fill this array by the request using any method you want. Only fill it with the request.
FileStream data = new FileStream("data.txt", FileMode.Open);
int i;
for ( i = 0; i < data.Length; i++)
{
mydata[i] = (byte)data.ReadByte();
}
data.Close();
Then I sent my data and waited for some time:
Stream clientstream = myclient.GetStream();
clientstream.Write(mydata, 0, 1000);
label1.Text = "Data Sent....";
Thread.Sleep(4000);
Then I received the result and wrote it on textbox
and on another file called response.txt:
data = new FileStream("response.txt", FileMode.Create);
StreamReader sr = new StreamReader(clientstream); textBox1.Text=sr.ReadToEnd();
data.Write(Encoding.ASCII.GetBytes(textBox1.Text), 0,
Encoding.ASCII.GetByteCount(textBox1.Text));
data.Close();
The contents of data.txt are:
POST /globalweather.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: text/xml; charset=utf-8
Content-Length: 571
SOAPAction: "http://www.webserviceX.NET/GetCitiesByCountry"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetCitiesByCountry xmlns="http://www.webserviceX.NET">
<CountryName>Egypt</CountryName>
</GetCitiesByCountry>
</soap:Body>
</soap:Envelope>
The contents of response.txt will be:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Length: 1728
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 09 Jan 2012 13:01:45 GMT
<?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
<GetCitiesByCountryResponse xmlns="http://www.webserviceX.NET">
<GetCitiesByCountryResult><NewDataSet>
<Table>
<Country>Egypt</Country>
<City>El Arish</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Asyut</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Alexandria / Nouzha</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Cairo Airport</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Hurguada</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Luxor</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Mersa Matruh</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Port Said</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Sharm El Sheikhintl</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>Asswan</City>
</Table>
<Table>
<Country>Egypt</Country>
<City>El Tor</City>
</Table>
</NewDataSet></GetCitiesByCountryResult></GetCitiesByCountryResponse>
</soap:Body></soap:Envelope>HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Mon, 09 Jan 2012 13:01:45 GMT
Connection: close
Content-Length: 326
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>
<hr><p>HTTP Error 400. The request verb is invalid.</p>
</BODY></HTML>
This function returns all the cities in Egypt as Dataset.