Copyright (c) Hyperion Entertainment and contributors.
AmiWest 2013 Lesson 4
Simple IP Clients & Servers
Simple network access is easy
Developing applications that use TCP/IP "sockets" for network communications have a reputation of being a challenging task. But AmigaOS and its Roadshow TCP/IP stack provides a couple of built-in shorthand mechanisms for easily creating simple network clients and servers: the TCP: handler and Roadshow's Superserver.
Using these Roadshow shortcuts, creating simple network client and server applications for single user or light-duty uses is no more complicated than reading or writing a file. The real challenge is understanding the protocol to be used (f.e. HTTP communications with web browsers) and being careful not to create a security risk on your or another user's Amiga.
An Internet Client
First, we will look at creating a small client to retrieve some simple information from an Internet website. Similar applications could be made to retrieve basic information like stock quotes, email contents, server conditions or other basic interactions. Aminet has a number examples of such clients written in ARexx that use the TCP: device that can be examined.
The Roadshow shortcut we will use is its built-in TCP: handler. This is mechanism that creates a virtual filesystem device ("TCP:") whenever Roadhsow gets online. To interact with a remote server, one just opens a file with the name being the URL of the server and port to be accessed.
Connect to the Server
To begin with, one opens a connection to the internet server as if one were opening a file. As described above, when Roadshow gets online, it creates a virtual TCP: device. To open a connection, one opens a file to the URL and port in question using this format:
TCP:<server URL>/<port number>
For example, to connect to the website "www.wunderground.com" one would use:
fileh = fopen("TCP:www.wunderground.com/80","r+");
The file name starts with TCP:, then the website URL and finally the port number - here "80" is site's HTTP port (used by almost all websites).
Typically, the port number reflects the type of port or protocol that is to be used. Such protocols could be FTP (file transfer), POP/SMTP (email) or many others. Port 80 is usually used for HTTP communications with websites.
If the file open request is successful, your Amiga is then connected to that server and any further interaction with the "fileh" file handle communicates directly with that port on that server. In this case, we would have connected to a websserver.
Talk to the Server
Once one has connected to a server, knowledge of the communications protoccol for that type of connection is required.
For each of those, a server expects a certain format of interaction to proceed and respond. Fortunately, common protocols are publicly documented.
http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
For each protocol there is usually an "RFC" document that describes how one uses the protocol, interacts with the port and accomplishes that protocol's goals.
In the case of "HTTP" (or a "Hypertext Transfer Protocol") connection to a webserver, we are usually expected to submit a "GET" request. Here are a couple more complete references on the HTTP protocol:
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
http://tools.ietf.org/html/rfc2616
To keep things simple, lets just look at submitting a "GET" request, such as a web browser, like IBrowse, would do. A simple HTTP version 1.1 GET request would include the following lines:
GET /<path> HTTP/1.1 host: <domain> user-agent: IBrowse/2.4 (AmigaOS 4.1; PPC; 68K build) Pragma: no-cache Accept-Language: en, * Accept: text/html;level=3 Accept: text/html;version=3.0 Accept: */* <blank line>
The <path> would be the rest of the URL (if any) on that system and <domain> is the name of the server.
Using the "WeatherUnderground" website URL from above and their pathname for searching for airport conditions, we can find the current conditions at Washington's Dulles International Airport with these domain & path values:
URL = www.wunderground.com PATH = cgi-bin/findweather/getForecast?query=IAD
The GET request syntax can be transcribed into C code which builds the entire request in a string and then sends it to the server with a simple "fprintf" to our open file handle, as follows:
// build web req text strcpy(line,"GET /"); strcat(line,path); strcat(line," HTTP/1.1\r\n"); strcat(line,"host: "); strcat(line,domain); strcat(line,"\r\n"); strcat(line,"user-agent: IBrowse/2.4 (AmigaOS 4.1; PPC; 68K build)\r\n"); strcat(line,"Pragma: no-cache\r\n"); strcat(line,"Accept-Language: en, *\r\n"); strcat(line,"Accept: text/html;level=3\r\n"); strcat(line,"Accept: text/html;version=3.0\r\n"); strcat(line,"Accept: */*\r\n"); strcat(line,"\r\n");
// send web req line to server fprintf(fileh,"%s",line);
As you can see, the variables "path" and "domain" are used to fill in some blanks in the request. The blank line at the end completes the GET request, after which the server will reply using the same file handle.
Listen to the Server
Once the GET request has been sent to the webserver, the server will start sending back either the requested webpage (or other content) or an error page. To see what sort of content is returned by the server, you can combine the domain and path values above and enter them in your web browser:
www.wunderground.com/cgi-bin/findweather/getForecast?query=IAD
Once the page is loaded, viewing the page source (f.e., IBrowse menu item "Page/Display Source...") will show you the same text that your program will receive after sending the get request.
As such, your program needs to start reading from the same file handle the request was sent with. This loop will print out the first hundred lines returned:
// read in the response count = 0; while( (fgets(inStr,MAX_STR,fileh) != NULL) && (count<100) ) { ++ count; printf("line %ld = %s\n",count,inStr); }
After the returned content has been read, output or otherwise processed, simply closing the file handle will close the connection to the server:
fclose(fileh);
All of these elements are combined in the following example program "IPClient.c" that asks you for a IATA airport code (IAD = Washington Dulles, FRA=Frankfurt, SYD=Sydney), then parses & prints out the weather conditions from the returned page.
Please Note: this example program worked with the wunderground.com website in 2013-2014, as the served webpages change over time, it is likely the parsing in this example is likely to fail and the program no longer return useful information.