Contents:
Networking Primer
Socket API and IO::Socket
Handling Multiple Clients
Real-World Servers
IO Objects and Filehandles
Prebuilt Client Modules
Resources
I plugged my phone in where the blender used to be. I called someone. They went "Aaaaahhh..."
- Steven Wright
Programs can communicate with each other in a variety of ways. They can use files, anonymous/named pipes, System V interprocess messaging primitives, BSD sockets, and TLI (Transport Layer Interface). Socket and TLI communications come under the purview of "networking," a step up from the other IPC (interprocess communication) mechanisms, because they don't constrain the communicating processes to be on the same machine. This chapter provides a primer on socket communications and builds simple client/server configurations using Graham Barr's IO library (part of the standard Perl distribution). This knowledge is put to use in the next chapter, where we build an asynchronous message passing module, and another for doing remote procedure calls (RPC).
Networking is the second of four important technologies that we discuss in this book; the others are user interfaces, persistence, and code generation. This chapter, like the other three, is as much about the technology as it is about Perl's support for it. Andrew Tanenbaum's textbook on computer networks [5] is a wonderful introduction to computer networking. (I also rate it as one of the best computer books ever written.) This chapter provides just enough introduction to networks to work with Perl, sockets, and TCP/IP.
Mail (paper and electronic) and telephones are two distinct forms of communication. A telephone conversation is connection-oriented, because the caller and the called "own" the line (have a continuous link) until the end of the conversation. Connection-oriented communication guarantees message delivery, preserves the order in which messages are sent, and allows a stream of data to be sent. Mail, in contrast, is a connectionless mode of transfer, which transports information in packets (or datagrams) and gives no guarantees about message delivery and the order in which the packets are received. It has a higher overhead because each packet identifies its sender and the intended receiver; in contrast, a connection-oriented conversation proceeds without further ado, once the parties have identified themselves. Computer networks offer you a similar choice of connection versus connectionless mode of data transfer. It must be mentioned that there are connectionless protocols such as reliable UDP that do offer guaranteed delivery and sequence integrity.
The networking world assigns each computer an internet address, also called an IP address (short for Internet Protocol), a sequence of four bytes typically written in a dot sequence, like this: 192.23.34.1. (This will change with IPv6, because the world is fast running out of four-byte IP addresses.) Just as you have convenient phone aliases such as 1-800-FLOWERS, computers are often given unique aliases, such as www.yahoo.com. Now, many programs can run on one machine, and it is not enough to deliver a message to the machine: it has to be handed over to the appropriate application program running on that machine. A program can ask for one or more ports to be opened, the equivalent of a private mailbox or telephone extension. To send a message to a program, you need its full address: its machine name and the port on which it is listening. Standard applications such as ftp, telnet, and mail actually come in pairs; for example, the ftp program you use talks to a counterpart server program called ftpd (ftp daemon) on the remote computer. Such server programs listen on standard port numbers; when you type www.yahoo.com on your web browser, the browser automatically connects to port 80 on that machine, where it assumes the corresponding web server to be listening. Port numbers 1-1024 are reserved for standard, well-known Internet applications. Many platforms reserve the name "localhost" (and the address 127.0.0.1) to mean the machine on which the program is running.
Once assigned a socket, your program has a choice of using a connection-oriented protocol called TCP/IP (Transport Control Protocol/IP) or a connectionless one, UDP/IP (User Datagram Protocol). Clearly, sender and receiver must use the same protocol. The TCP/IP model is usually preferred over UDP because it provides for data sequencing, end-to-end reliability (checksums, positive acknowledgments, time-outs), and end-to-end flow control (if the sender is sending data faster than the receiver can handle it, it will block the sender when the receiver's buffers are full). If the communications medium is very good, such as a LAN, UDP may perform much better because it doesn't spend time accounting for the worst case. In a production system, however, you can never really take a chance, so we will stick to TCP in this chapter.
The socket abstraction and API were introduced in BSD 4.2 to provide a uniform interface over different types of protocols (there are others besides TCP and UDP), and, depending on the protocol used, a socket behaves like either a telephone receiver or a mailbox. In either case, it takes one socket on each side to make a conversation (which is why sockets are also known as communications end-points). The socket API allows you to specify the domain of the communicating entities - the "Unix domain" is used for processes on the same machine, and the "Internet domain" is used for processes on different machines. This chapter examines the more generally accepted (and useful) "Internet domain" option.
TLI (Transport Layer Interface), another API introduced in System V (Release 3.0, 1986), provides a very similar-looking alternative to the socket abstraction, but because it is not as widely used as the BSD socket interface, we will not discuss it in this chapter.