PERL Socket - Networking Programing

NOTE: If you are aware of Unix Sockets then you can leave introduction part

What is a socket?

Just another bit of computer jargon? Going back a little into networking history, it is a Berkeley UNIX mechanism of creating a virtual duplex connection between processes. This was later ported on to every known OS enabling communication between systems across geographical location running on different OS software. If not for the socket, most of the network communication between systems would never ever have happened.
Taking a closer look; a typical computer system on a network receives and sends information as desired by the various applications running on it. This information is routed to the system, since a unique IP address is designated to it. On the system, this information is given to the relevant applications which listen on different ports. For example a net browser listens on port 80 for information. Also we can
write applications which listen and send information on a specific port number.
For now, let's sum up that a socket is an IP address and a port, enabling connection.
To explain the socket we will take an example of Client - Server Programming. To complete a client server architecture we would have to go through the following steps

Creating A Server

  • Create a socket with socket call.
  • Bind the socket to a port address with bind call.
  • Listen to the socket at the port address with listen call.
  • Accept client connections with accept call.

Creating A Client

  • Create a socket with socket call.
  • Connect (the socket) to the remote machine with connect call.

Create a socket

The first step in establishing a network connection is creating a socket, with the sockt() function
socket( SOCKET, DOMAIN, TYPE, PROTOCOL ); creates a socket 
socket creates a SOCKET. The other three arguments are integers which should have the following values for TCP/IP connections.
  • DOMAIN should be PF_INET. It's probable 2 on your computer.
  • TYPE should be SOCK_STREAM for TCP/IP connection.
  • PROTOCOL should be (getprotobyname('tcp'))[2]. It is the particular protocol such as TCP to be spoken over the socket.
So socket function call will be something like this:
  use Socket     #defines PF_INET and SOCK_STREAM
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]);


Bind to a socket address

The sockets created by socket are innocent and they have not yet been polluted by a computer hostname or a port number. Next socket function bind() fleshes out the socket with these values. Server uses bind() function to specify the port at which they will be accepting connections from the clients.
 bind( SOCKET, ADDRESS ) binds a network ADDRESS to a SOCKET.
ADDRESS is a socket address which ( for TCP/IP ) is a packet string containing three elements
  1. The address family (For TCP/IP, that's AF_INET, probably 2 on your system )
  2. The port number ( for example 21 )
  3. The internet address of the computer ( for example 10.12.12.168 )
As the bind() is used by a server which does not need to know its own address so the argument list looks like this:
   $port = 12345;    # the port 
bind( SOCKET, pack( 'Sn4x8', AF_INET, $port, "" ))
or die "Can't bind to port $port! n";
The or die clause is very important - if a server dies without outstanding connections the port won't be immediately reusable unless you use the option SO_REUSEADDR using setsockopt()function. Here pack() function is being used to pack all the data into binary format.

Listening on the port

If this is a server program then it is required to issue a call to listen() on the specified port.
 listen( SOCKET, QUEUESIZE );
The above call is mandatory for all the servers and here QUEUESIZE is the maximum number of outstanding connection request allowed. Generally, listen() is used in an infinite loop. As soon as one connection arrives the server deals with it and then goes back to listen for more connections.

Accepting connections

If this is a server program then it is required to issue a call to access() function to accept the incoming connections.
accept( NEW_SOCKET, SOCKET );
The accept call receive SOCKET descriptor returned by socket() function. Upon successful completion of this call, a new socket descriptor is returned. All future communication between client and server then takes place over NEW_SOCKET and SOCKET returns to what it does best : listen()ing for a new connection. If access() call fails then it returns FLASE which is defined in Socket module which we have used initially.
You will often see accept() used inside a while loop as follows
   while(1) {
accept( NEW_SOCKET, SOCKT );
.......
}
Now all the calls related to server are over and let us see a call which will be required by the client

Connection Establishment

If you are going to prepare client program then after using socket() call you would have to use another call connect() to connect to the server.
 connect( SOCKET, ADDRESS );
Here ADDRESS is a socket address similar to bind call, except that it contains the IP address of the remote server.
   $port = 21;    # the  ftp port
$server_ip_address = "10.12.12.168";
connect( SOCKET, pack( 'Sn4x8', AF_INET, $port, $server ))
or die "Can't connect to port $port! n";
If you connect to the server successfully then you can start sending your commands to the server using SOCKET descriptor.
So now lets put all the things together

Script to Create a Server

#!/usr/bin/perl -w
# server.pl
#--------------------

use strict;
use Socket;

# use port 7890 as default
my $port = shift || 7890;
my $proto = getprotobyname('tcp');

# create a socket, make it reusable
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
or die "Can't open socket $!n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
or die "Can't set socket option to SO_REUSEADDR $!n";

# bind to a port, then listen
bind( SOCKET, pack( 'Sn4x8', AF_INET, $port, "" ))
or die "Can't bind to port $port! n";
listen(SOCKET, 5) or die "liste
n: $!";
print "SERVER started on port $portn";

# accepting a connection
my $client_addr;
while ($client_addr = accept(NET_SOCKET, SOCKET)) {
# send them a message, close connection
print NEW_SOCKET "Smile from the server";
close NEW_SOCKET;
}

Now starting above Server

To run the server in background mode issue the following command on Unix prompt
$sever.pl&


Script to Create a Client

#!/usr/bin/perl -w
# client.pl
#----------------

use strict;
use Socket;

# initialize host and port
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "10.12.12.168";

# create the socket, connect to the port
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
or die "Can't create a socket $!n";
connect( SOCKET, pack( 'Sn4x8', AF_INET, $port, $server ))
or die "Can't connect to port $port! n";

my $line;
while ($line = <SOCKET>) {
print "$linen";
}
close SOCKET or die "close: $!";

No comments:

Post a Comment