Copyright (c) Hyperion Entertainment and contributors.
Difference between revisions of "AmiWest 2013 Lesson 4"
Paul Sadlik (talk | contribs) |
Paul Sadlik (talk | contribs) |
||
Line 16: | Line 16: | ||
− | An Internet Client |
+ | ==An Internet Client== |
First, we will look at creating a small client to retrieve some simple |
First, we will look at creating a small client to retrieve some simple |
||
Line 30: | Line 30: | ||
file with the name being the URL of the server and port to be accessed. |
file with the name being the URL of the server and port to be accessed. |
||
− | Connect to the Server |
+ | ===Connect to the Server=== |
To begin with, one opens a connection to the internet server as if one |
To begin with, one opens a connection to the internet server as if one |
||
Line 37: | Line 37: | ||
to the URL and port in question using this format: |
to the URL and port in question using this format: |
||
+ | <syntaxhighlight> |
||
TCP:<server URL>/<port number> |
TCP:<server URL>/<port number> |
||
+ | </syntaxhighlight> |
||
For example, to connect to the website "www.wunderground.com" one would |
For example, to connect to the website "www.wunderground.com" one would |
||
use: |
use: |
||
+ | <syntaxhighlight> |
||
fileh = fopen("TCP:www.wunderground.com/80","r+"); |
fileh = fopen("TCP:www.wunderground.com/80","r+"); |
||
+ | </syntaxhighlight> |
||
The file name starts with TCP:, then the website URL and finally the |
The file name starts with TCP:, then the website URL and finally the |
||
Line 57: | Line 61: | ||
we would have connected to a websserver. |
we would have connected to a websserver. |
||
− | Talk to the Server |
+ | ===Talk to the Server=== |
Once one has connected to a server, knowledge of the communications |
Once one has connected to a server, knowledge of the communications |
||
Line 84: | Line 88: | ||
request would include the following lines: |
request would include the following lines: |
||
+ | <syntaxhighlight> |
||
GET /<path> HTTP/1.1 |
GET /<path> HTTP/1.1 |
||
host: <domain> |
host: <domain> |
||
Line 93: | Line 98: | ||
Accept: */* |
Accept: */* |
||
<blank line> |
<blank line> |
||
+ | </syntaxhighlight> |
||
The <path> would be the rest of the URL (if any) on that system and |
The <path> would be the rest of the URL (if any) on that system and |
||
Line 101: | Line 107: | ||
Washington's Dulles International Airport with these domain & path values: |
Washington's Dulles International Airport with these domain & path values: |
||
+ | <syntaxhighlight> |
||
URL = www.wunderground.com |
URL = www.wunderground.com |
||
PATH = cgi-bin/findweather/getForecast?query=IAD |
PATH = cgi-bin/findweather/getForecast?query=IAD |
||
+ | </syntaxhighlight> |
||
The GET request syntax can be transcribed into C code which builds the entire |
The GET request syntax can be transcribed into C code which builds the entire |
||
Line 108: | Line 116: | ||
open file handle, as follows: |
open file handle, as follows: |
||
+ | <syntaxhighlight> |
||
// build web req text |
// build web req text |
||
strcpy(line,"GET /"); |
strcpy(line,"GET /"); |
||
Line 125: | Line 134: | ||
// send web req line to server |
// send web req line to server |
||
fprintf(fileh,"%s",line); |
fprintf(fileh,"%s",line); |
||
+ | </syntaxhighlight> |
||
As you can see, the variables "path" and "domain" are used to fill in some |
As you can see, the variables "path" and "domain" are used to fill in some |
||
Line 130: | Line 140: | ||
after which the server will reply using the same file handle. |
after which the server will reply using the same file handle. |
||
− | Listen to the Server |
+ | ===Listen to the Server=== |
Once the GET request has been sent to the webserver, the server will start |
Once the GET request has been sent to the webserver, the server will start |
||
Line 137: | Line 147: | ||
domain and path values above and enter them in your web browser: |
domain and path values above and enter them in your web browser: |
||
+ | <syntaxhighlight> |
||
www.wunderground.com/cgi-bin/findweather/getForecast?query=IAD |
www.wunderground.com/cgi-bin/findweather/getForecast?query=IAD |
||
+ | </syntaxhighlight> |
||
Once the page is loaded, viewing the page source (f.e., IBrowse menu item |
Once the page is loaded, viewing the page source (f.e., IBrowse menu item |
||
Line 147: | Line 159: | ||
lines returned: |
lines returned: |
||
+ | <syntaxhighlight> |
||
// read in the response |
// read in the response |
||
count = 0; |
count = 0; |
||
Line 153: | Line 166: | ||
++ count; |
++ count; |
||
printf("line %ld = %s\n",count,inStr); |
printf("line %ld = %s\n",count,inStr); |
||
+ | |||
+ | // process lines received here ! |
||
} |
} |
||
+ | </syntaxhighlight> |
||
+ | |||
+ | Within this loop your applcation can parse the received lines for whatever |
||
+ | data your application is tryng to obtain. In the case of our example program below, |
||
+ | the program searches for a string precedes the weather information we want. |
||
After the returned content has been read, output or otherwise processed, |
After the returned content has been read, output or otherwise processed, |
||
simply closing the file handle will close the connection to the server: |
simply closing the file handle will close the connection to the server: |
||
+ | <syntaxhighlight> |
||
fclose(fileh); |
fclose(fileh); |
||
+ | </syntaxhighlight> |
||
All of these elements are combined in the following example program |
All of these elements are combined in the following example program |
||
− | "IPClient.c" that asks you for a IATA airport code (IAD = Washington |
+ | "IPClient.c" that asks you for a IATA airport code (f.e., IAD = Washington |
Dulles, FRA=Frankfurt, SYD=Sydney), then parses & prints out the weather |
Dulles, FRA=Frankfurt, SYD=Sydney), then parses & prints out the weather |
||
conditions from the returned page. |
conditions from the returned page. |
Revision as of 20:33, 13 April 2014
Contents
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); // process lines received here ! }
Within this loop your applcation can parse the received lines for whatever data your application is tryng to obtain. In the case of our example program below, the program searches for a string precedes the weather information we want.
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 (f.e., 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.