Introduction to IO::Sockets
A client and server program works this way. Simply put, a client requests a service and a server services the request. There are several ways to do this. The crudest will be to call a program within Perl and pass the parameters during the call. Another way is to use pipes.A program can call another program but the input to the called program will be passed through the STDIN of the other program. Both methods are crude and allow only for simple passing of input and output. Another way to do this is using sockets.
Sockets allow two programs to communicate with each other. The server binds a port on the machine. The client connects to that port to communicate with the server,
IO:Socket Module
Perl has a module that simplifies socket communication. It is called IO::Socket. Simply put, the client has to connect to the server socket. The server meanwhile has to get the port and listen toanything coming in on that socket.
Server script
The server is the program that listens to a request and processes the request. For our exercise, we will write a simple server that accepts numbers and adds all numbers up. (I know, you might as well do this in the client program but this is just an illustration)The script has to do the following:
- Open the listening socket by specifying the protocol, local host address and the port
- Actually listen to any requests
- When a request is accepted, process the request
- Return the result to the client
The code to do this is as follows:
use IO::Socket; #####################################
# Server Script:
# Copyright 2003 (c) Philip Yuson
# this program is distributed according to
# the terms of the Perl license
# Use at your own risk
#####################################
$local = IO::Socket::INET->new(
Proto => 'tcp', # protocol
LocalAddr => 'localhost:8081',
# Host and port to listen to
# Change the port if 8081 is being used
Reuse => 1
) or die "$!";
$local->listen(); # listen
$local->autoflush(1); # To send response immediately
print "At your service. Waiting...\n";
my $addr; # Client handle
while ($addr = $local->accept() ) { # receive a request
print "Connected from: ", $addr->peerhost();
# Display messages
print " Port: ", $addr->peerport(), "\n";
my $result; # variable for Result
while (<$addr>) { # Read all messages from client
# (Assume all valid numbers)
last if m/^end/gi; # if message is 'end'
# then exit loop
print "Received: $_"; # Print received message
print $addr $_; # Send received message back
# to verify
$result += $_; # Add value to result
}
chomp; # Remove the
if (m/^end/gi) { # You need this. Otherwise if
# the client terminates abruptly
# The server will encounter an
# error when it sends the result back
# and terminate
my $send = "result=$result"; # Format result message
print $addr "$send\n"; # send the result message
print "Result: $send\n"; # Display sent message
}
print "Closed connection\n"; # Inform that connection
# to client is closed
close $addr; # close client
print "At your service. Waiting...\n";
# Wait again for next request
}
|
Start a command window and run this. The output should show something like this:
At your
service. Waiting...
This means that the server is listening to any request on the given port.
Client Script
The client drives the process. It sends a request to the server. It has to connect to the port the server is listening to. It should then receive some form of input from STDIN to send to the server. At the end, it sends an 'end' message to the server.To illustrate interactive communication, the server will echo back anything it receives from the client. The client then verifies this against what it sent. If it does not match, then it is an error.
When the client receives an 'end' from STDIN, it receives the result from the server and prints out the result.
Ready for the code?
use IO::Socket;
#####################################
# Client Script:
# Copyright 2003 (c) Philip Yuson
# this program is distributed according to
# the terms of the Perl license
# Use at your own risk
#####################################
$remote = IO::Socket::INET->new(
Proto => 'tcp', # protocol
PeerAddr=> 'localhost', # Address of server
PeerPort=> "8081", # port of server
Reuse => 1,
) or die "$!";
print "Connected to ", $remote->peerhost, # Info message
" on port: ", $remote->peerport, "\n";
$remote->autoflush(1); # Send immediately
while (<>) { # Get input from STDIN
print $remote $_; # Send to Server
last if m/^end/gi; # If 'end' then exit loop
my $line = <$remote>; # Receive echo from server
if ($line ne $_) { # If not the same as input
print "Error in sending output\n"; # error
exit; # Terminate
}
}
my $res = <$remote>; # Receive result from server
$res =~ m/result=(\d*)/gi; # Get the numeric result from message
print "Result: $1\n"; # Print the result
print "End of client\n"; # End of client
close $remote; # Close socket
|
Save this as client.pl.
Start another command window and run this. Make sure that the server.pl is running also.
The client should display something like this:
Connected
to 127.0.0.1 on port: 8081
Type in any set of numbers and press <Enter> each time. When you are done, type end and press <Enter>. Look at the result. The server should return the right computation.
Where can you use this?
The server can take the place of say a tax calculation routine where you send all the relevant numbers and at the end receive the calculated tax.The server can also be modified to perform database access and return the result to the client. The
client can send a message like select tablename. The server can then format the proper SQL statement to get the rows. With this method, programmers on the client side need not worry about SQL statements because the programmers with SQL skills can write the SQL statements on the server side.
No comments:
Post a Comment