Contents:
A Simple Client
A Webget Client
Few computers (or computer users, for that matter) are content to remain isolated from the rest of the world. Networking, once mostly limited to government research labs and computer science departments at major universities, is now available to virtually everyone, even home computer users with a modem and dial-up SLIP or PPP service. More than ever, networking is now used daily by organizations and individuals from every walk of life. They use networking to exchange email, schedule meetings, manage distributed databases, access company information, grab weather reports, pull down today's news, chat with someone in a different hemisphere, or advertise their company on the Web.
These diverse applications all share one thing in common: they use TCP networking, the fundamental protocol that links the Net together.[ 1 ] And we don't just mean the Internet, either. Firewalls aside, the underlying technology is the same whether you're connecting far across the Internet, between your corporate offices, or from your kitchen down to your basement. As a result, you only have to learn one technology for all sorts of application areas.
[1] Actually, IP (Internet Protocol) ties the Internet together, but TCP/IP is just a layer on top of IP.
How can you use networking to let an application on one machine talk to a different application, possibly on a totally different machine? With Perl, it's pretty easy, but first you should probably know a little bit about how the TCP networking model works.
Even if you've never touched a computer network before in your whole life, you already know another connection-based system: the telephone system. Don't let fancy words like "client-server programming" put you off. When you see the word "client," think "caller"; when you see the word "server," think "responder." If you ring someone up on the telephone, you are the client. Whoever picks up the phone at the other end is the server.
Programmers with a background in C programming may be familiar with sockets . A socket is the interface to the network in the same sense that a filehandle is the interface to files in the filesystem. In fact, for the simple stream-based clients we're going to demonstrate below, you can use a socket handle just as you would a filehandle.[ 2 ]
[2] Well, almost; you can't seek on a socket.
You can read from the socket, write to it, or both. That's because a socket is a special kind of bidirectional filehandle representing a network connection. Unlike normal files created via
open
, sockets are created using the low-level
socket
function.
Let's squeeze a little more mileage out of our telephone model. When you call into a big company's telephone switchboard, you can ask for a particular department by one name or another (such as Personnel or Human Resources), or by an exact number (like extension 213). Think of each service running on a computer as a department in a large corporation. Sometimes a particular service has several different names, such as both
http
and
www
, but only one number, such as 80. That number associated with a particular service name is its
port
. The Perl functions
getservbyname
and
getservbyport
can be used to look up a service name given its port number, or vice versa.
Table C.1
lists some standard TCP services and their port numbers.
Service |
Port |
Purpose |
---|---|---|
echo |
7 |
Accepts all input and echoes it back |
discard |
9 |
Accepts anything but does nothing with it |
daytime |
13 |
Returns the current date and time in local format |
ftp |
21 |
Server for file-transfer requests |
telnet |
23 |
Server for interactive telnet sessions |
smtp |
25 |
Simple mail transfer protocol; the mailer daemon |
time |
37 |
Return number of seconds since 1900 (in binary) |
http |
80 |
The World Wide Web server |
nntp |
119 |
The news server |
Although sockets were originally developed for Berkeley UNIX, the overwhelming popularity of the Internet has induced virtually all operating-systems vendors to include socket support for client-server programming. For this book, directly using the
socket
function is a bit low level. We recommend that you use the more user-friendly
IO::Socket module
,[
3
] which we'll use in all our sample code. Consequently, we'll also be employing some of Perl's object-oriented constructs. For a brief introduction to these constructs, see
Chapter 18,
CGI Programming
. The
perltoot
documentation (starting with Perl 5.004) and
Chapter 5
of
Programming Perl
offer a more complete introduction to object-oriented programming in Perl.
[3]
IO::Socket
is included as part of the standard Perl distribution as of the 5.004 release and the current ActiveState at the time of this writing. If you're running an earlier version of Perl, just fetchIO::Socket
from CPAN.
We don't have the space in this book to provide a full TCP/IP tutorial, but we can at least present a few simple clients. For servers, which are a bit more complicated, see Chapter 6 of Programming Perl . Generally speaking, writing servers in Perl on Windows NT is a difficult task because Perl doesn't currently offer support for threads, and there's no easy way to implement support for multiple simultaneous clients. This may change in the future, so stay tuned for future Perl releases.
For our simplest client, we'll choose a rather boring service, called "daytime." The daytime server sends a connecting client one line of data containing the time of day on that remote server, then closes the connection.
Here's the client:
use IO::Socket; $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "localhost", PeerPort => "daytime(13)", ) or die "cannot connect to daytime port at localhost"; while ( <$remote> ) { print }
When you run this program, you should get something back that looks like this:
Thu May 8 11:57:15 1997
Here are what those parameters to the
new
constructor mean:
Proto
The protocol to use. In this case, the socket handle returned will be connected to a TCP socket, because we want a stream-oriented connection, that is, one that acts pretty much like a plain old file. Not all sockets are of this type. For example, the UDP protocol can be used to make a datagram socket, used for message-passing.
PeerAddr
The name or Internet address of the remote host the server is running on. We could have specified a longer name like
www.perl.com
, or an address like
204.148.40.9
. For demonstration purposes, we've used the special hostname
localhost
, which should always mean the current machine you're running on. The corresponding Internet address for localhost is
127.0.0.1
, if you'd rather use that.
PeerPort
This is the service name or port number we'd like to connect to. We could have gotten away with using just
daytime
on systems with a well-configured system services file,[
4
] but just in case, we've specified the port number (13) in parentheses. Using just the number would also have worked, but numbers as constants make careful programmers nervous.
[4] The system services file is in %windir%/system32/drivers/etc/services under Windows NT.
Notice how the return value from the
new
constructor is used as a filehandle in the
while
loop? That example is an indirect filehandle, which is a scalar variable containing a filehandle. You can use this filehandle as you would a normal filehandle. For example, you can read one line from it this way:
$line = <$handle>;
Or all remaining lines from it this way:
@lines = <$handle>;
And send a line of data to it this way:
print $handle "some data\n";