![]() | ![]() | ![]() | GNetwork Library Manual | ![]() |
---|
Getting Started — Figuring out what your sub-class needs
For the purposes of this tutorial, imagine a protocol called "FLP" (File Leeching Protocol :-)), a very basic protocol designed to handle file downloading. FLP has four commands sent in raw ASCII:
Command | Success Reply | Error Replies |
---|---|---|
LOGIN {username} {passwd} | FLP LOGGED_IN | FLP BADUSERPASS |
GET {filename} {offset} | FLP STARTGET {file size} | FLP NOTFOUND, FLP BADPERMS, FLP DONEGET |
STOP | FLP STOPPED | FLP NOTRANSFER |
QUIT | (None) | (None) |
? | (None) | FLP UNKNOWN |
The "FLP" protocol obviously supports logins, downloads, and download resuming (downloads which can be picked up later on via the "offset" argument). It also and can download multiple files over a single open connection, one at a time (similar to HTTP/1.1's keep-alive feature). The "FLP" protocol also supports cancelling a download by sending a STOP command while the transfer is in progress.
Given the information about the "FLP" protocol, the most important part of sub-classing GTcpConnection is making sure that the object capabilities match the capabilities of the protocol in a way that is easy to use by both a programmer, and (through the application) the user interface. This may seem strange, but it often helps to design the user interface first, and decide how the user will interact with the network connection (if at all) before writing the protocol object. The main reason for doing this is to prevent having to go back and re-write the sub-class while you're designing the interface, or worse, having to hack the user interface to match the sub-class.
That said, some aspects of creating protocol-specific sub-classes of GTcpConnection are nearly universal. In virtually every protocol, after the basic TCP/IP socket connection is open and ready to send and receive data, some basic authentication is sent or recieved to indicate that the connection is also open on the protocol level, and read to send or receive protocol-specific information. Most protocols also include some form of a QUIT command, which causes the server to close the connection.
However, GTcpConnection is a basic networking wrapper, and does not handle anything but basic networking. Therefore, the "closed" and "connect-done" signals for GTcpConnection objects are generally insufficient for most protocols. Likewise, the "status" property is generally insufficient to handle the various states that a protocol can handle (ready, downloading, etc.). The FLP protocol described above can be closed, closing, ready, logging in, or transferring a file.
Because of this, sub-classes will generally share at least one property and two signals. A protocol-based status property, and some form of protocol-level "connection-is-ready" and "closed" signals. The recommend names are "connect-complete" and "quit" for the signals, and "{protocolname}-status" for the property.
For the sake of our object, let's say we're going to use it for a download manager, which will display a progress dialog for each file which is downloaded. Our object therefore needs signals to indicate when a download has started, when a download has finished (or been cancelled). Since the protocol also includes the concept of error messages, an "error" signal would also be useful. If we want our object to save the file itself, then it would make sense to also include a "download-progress" signal, to indicate how far along the download is. However, for this case, we're going to let the application save the data itself.
So, our object is going to have "connect-complete", "quit", "error", "download-start", and "download-done" signals. The "download-start" signal should probably also include the total size of the file to be downloaded (in bytes) and how much of the file we're skipping (the offset). Likewise, the "download-done" signal should probably also indicate whether the download was actually completed or not.
As far as properties, our object should have a read-only "flp-status" property to indicate what the object is doing on the protocol level, and read-only "filename", "filesize", and "offset" properties, to indicate information about the current file being transferred. It should also have read-write "username" and "passwd" properties, because those are required to login to the server. Now that we know what all needs to go into the object, we can start writing it.
<< Client Application Tutorial | Sub-Classing >> |