Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Internet Socket Programming Using Perl


November, 2004: Internet Socket Programming Using Perl

Thomas is a writer residing in Selkirk, Manitoba, Canada. He can be contacted at [email protected].


The role of Perl on the Internet is hard to ignore. Some would make the case that Perl is the most used and most capable scripting language on the Internet today, and this is probably true. Its versatility and ease of use has made it an industry standard, used throughout the world.

Perl sockets work like file handles that can span a network or the entire Internet. With sockets, you can communicate with any computer that is connected via the Internet or via a network by specifying the server to connect to and a port to connect through. After the initial connection, you may use that connection just as you would a file handle. There are a few differences, but these are mainly academic.

To put it simply, the two sides of a Perl socket are the server and the client. It doesn't really matter which is which—the communication process is essentially the same because the client can send information to the server, and vice versa. The communication process is surprisingly simple. The process starts with the creation of the server. The server waits for a connection request from the client, which can be created any time after the creation of the server. The client connects to the server using the address of the server and the mutually agreed upon port number. If the port numbers are different, no connection is made. Once the client is connected, data may be sent from the server to the client, and vice versa.

There are two ways that data may be sent over a socket: two-way using one socket, or one-way using two sockets. In the one-socket method, data is sent from the server to the client and from the client to the server using one socket for both. In the two-socket method, one socket is used to send data from the server to the client and one is used to send data from the client to the server. I'll cover both methods in this article.

Sockets exist on all major operating systems. They are the accepted way to achieve communication between computers. Keeping this in mind, you can connect a UNIX computer to a Windows computer (and vice versa) with little or no trouble—if Perl is successfully installed on both machines. It should be noted that the ports used for an operation like this differ from OS to OS. Just keep in mind a few simple facts: Ports below 1024 are normally reserved for system use, so save yourself the headache and don't use them. HTTP requests usually use port 80, for example. Using a port number roughly in the 1025 to 5000 range usually produces adequate results. Just be sure to use the same port on both computers being connected. Now, let's get to the practical coding.

Before you can connect to a server, or even create the server, you must know whether you can establish a connection on that port. To do this, use the can_read or can_write methods of the IO::Select module, which is included with Perl. The following example checks four sockets to see which ones are available for the connection.

Use IO::Select

$select = IO::Select->new();

$select->add($socket1);
$select->add($socket2);
$select->add($socket3);
$select->add($socket4);

@ok_to_read = $select->can_read($timeout);

foreach $socket (@ok_to_read) {
  $socket->recv($data_buffer, $flags)
  print $data_buffer;
}

This example uses the can_read method to check if any of the sockets may be used. You can just as easily use the can_write method in this particular example—the end result is the same. The script starts with the declaration of the use of the IO::Select module. A new instance named $select is created, then the four sockets are created using the add() method. The sockets are placed into the @ok_to_read array, where the can_read method is invoked. A foreach loop is then used to print the results from the can_read call to the contents of the @ok_to_read array. The recv method is used to send info through the socket. Using the recv or send functions, you can send byte streams through your socket. You can also use the simple print and angle operators (< and >) to send text through the socket. Just be sure to use the newline character (\n) at the end of each line if you're sending text; the newline character is required to send the text string through the socket—if there is no newline character, no data is sent.

Now that you know how to check the sockets, we can delve into the creation of the common servers and clients that Perl is able to use. We'll start with the creation of a TCP server and a TCP client using IO::Socket. Since both the server and the client work hand in hand, we'll cover them both at the same time. There are, however, a few bases that we have to cover—namely, the eight parameters that are passed to the new() method of IO::Socket::INET.

PeerAddr—The DNS address of the machine you'd like to connect to. The address may be the dotted IP address of the machine, or the domain name itself; "walkthegeek.com," for example.

PeerPort—The port on the host machine you'd like to connect to. We'll use port 2000, for no particular reason.

Proto—The protocol that will be used, the options being tcp or udp.

Type—The type of connection you'd like to establish, the options being SOCK_STREAM for tcp data, SOCK_DGRAM for udp connections, or SOCK_SEQPACKET for sequential data packet connections. We'll be using tcp, so the SOCK_STREAM connection type will be used.

LocalAddr—The local address to be bound, if there is one. We won't use one.

LocalPort—The local port number to be used.

Listen—The queue size, which is the maximum number of connections allowed.

Timeout—The timeout value for connections.

All socket communications using IO::Socket use these same parameters. We'll use the new() method of IO::Socket::INET to return a scalar that holds a filehandle, which is an indirect file handle type. Let's make a client:

use IO::Socket

$socket = IO::Socket::INET->new
  (
  PeerAddr => 'walkthegeek.com',
  PeerPort => '2000',
  Proto => 'tcp',
  Type = 'SOCK_STREAM'
  ) or die "Could not Open Port.\n";

So there you go. You've made a TCP client using the sockets of IO::Socket::INET. Now let's write to the server from the client. The connection coding is the same, so it doesn't need to be repeated. As in the previous example, the port used is 2000, the server is walkthegeek.com, the protocol is tcp, and the type is SOCK_STREAM:

print $socket "Hello there!!\n";

close ($socket);

The example sends a text message to the server. The message "Hello there!!" will be displayed on the server's console. Notice that the newline character (\n) has been dutifully used on the end of the print statement.

To read from the server, the creation of the socket and the subsequent connection is the same, and only the print statement changes:

$answer = <$socket>;

print $answer;

close ($socket);

The above code pulls the message from the server, displaying it on the console of the client. Creating a server is as easy as creating the client. The same connection coding is used, only the $socket is replaced with $server:

$server = IO::Socket::INET->new
  (
  PeerAddr => 'walkthegeek.com',
  PeerPort => '2000',
  Proto => 'tcp',
  Type = 'SOCK_STREAM'
  ) or die "Could not Open Port.\n";

What is different in the creation of the client as opposed to the creation of the server is the coding below the connection snippet—a while loop is used. Here's an example showing the server reading from the client:

while ($client = $server->accept())

{

  $line = <$client>;
  print $line;
  }

close ($server);

The while loop calls the accept() method, which makes the server wait for a client to connect. The body of the while loop is executed when the client connects, reading (pulling) any messages from the client. To write to the client, the only thing that changes is the body of the while loop:

while ($client = $server->accept())
{
  print "Hello Client !!\n";
  }

close ($server);

In the examples so far, I've used tcp for the sockets. You can just as easily use udp, however. Just substitute udp for tcp in the Proto parameter, and use SOCK_DGRAM in place of SOCK_STREAM for the Type parameter.

In a nutshell, that's socket programming. With this knowledge, you can create chat programs, run a multiplayer game over the Internet, and just generally have fun. Some working, practical examples of the use of sockets are the Yahoo Messenger, MSN Messenger, and various other Java and Perl-based chat programs.

TPJ


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.