English 中文(简体)
Perl - Socket Programming
  • 时间:2024-10-18

Perl - Socket Programming


Previous Page Next Page  

What is a Socket?

Socket is a Berkeley UNIX mechanism of creating a virtual duplex connection between different processes. This was later ported on to every known OS enabpng 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 apppcations 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 apppcations, which psten on different ports. For example an internet browser pstens on port 80 for information received from the web server. Also we can write our custom apppcations which may psten and send/receive information on a specific port number.

For now, let s sum up that a socket is an IP address and a port, enabpng connection to send and recieve data over a network.

To explain above mentioned socket concept we will take an example of Cpent - Server Programming using Perl. To complete a cpent server architecture we would have to go through the following steps −

To Create a Server

    Create a socket using socket call.

    Bind the socket to a port address using bind call.

    Listen to the socket at the port address using psten call.

    Accept cpent connections using accept call.

To Create a Cpent

    Create a socket with socket call.

    Connect (the socket) to the server using connect call.

Following diagram shows the complete sequence of the calls used by Cpent and Server to communicate with each other −

Perl Socket

Server Side Socket Calls

The socket() call

The socket() call is the first call in estabpshing a network connection is creating a socket. This call has the following syntax −

socket( SOCKET, DOMAIN, TYPE, PROTOCOL );

The above call creates a SOCKET and 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 issued by the server will be something pke this −

use Socket     # This defines PF_INET and SOCK_STREAM

socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname( tcp ))[2]);

The bind() call

The sockets created by socket() call are useless until they are bound to a hostname and a port number. Server uses the following bind() function to specify the port at which they will be accepting connections from the cpents.

bind( SOCKET, ADDRESS );

Here SOCKET is the descriptor returned by socket() call and ADDRESS is a socket address ( for TCP/IP ) containing three elements −

    The address family (For TCP/IP, that s AF_INET, probably 2 on your system).

    The port number (for example 21).

    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 pst looks pke this −

use Socket        # This defines PF_INET and SOCK_STREAM

$port = 12345;    # The unique port used by the sever to psten requests
$server_ip_address = "10.12.12.168";
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
   or die "Can t bind to port $port! 
";

The or die clause is very important because 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_sockaddr_in() function is being used to pack the Port and IP address into binary format.

The psten() call

If this is a server program, then it is required to issue a call to psten() on the specified port to psten, i.e., wait for the incoming requests. This call has the following syntax −

psten( SOCKET, QUEUESIZE );

The above call uses SOCKET descriptor returned by socket() call and QUEUESIZE is the maximum number of outstanding connection request allowed simultaneously.

The accept() call

If this is a server program then it is required to issue a call to the access() function to accept the incoming connections. This call has the following syntax −

accept( NEW_SOCKET, SOCKET );

The accept call receive SOCKET descriptor returned by socket() function and upon successful completion, a new socket descriptor NEW_SOCKET is returned for all future communication between the cpent and the server. If access() call fails, then it returns FLASE which is defined in Socket module which we have used initially.

Generally, accept() is used in an infinite loop. As soon as one connection arrives the server either creates a child process to deal with it or serves it himself and then goes back to psten for more connections.

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 cpent.

Cpent Side Socket Calls

The connect() call

If you are going to prepare cpent program, then first you will use socket() call to create a socket and then you would have to use connect() call to connect to the server. You already have seen socket() call syntax and it will remain similar to server socket() call, but here is the syntax for connect() call −

connect( SOCKET, ADDRESS );

Here SCOKET is the socket descriptor returned by socket() call issued by the cpent and ADDRESS is a socket address similar to bind call, except that it contains the IP address of the remote server.

$port = 21;    # For example, the ftp port
$server_ip_address = "10.12.12.168";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
   or die "Can t connect to port $port! 
";

If you connect to the server successfully, then you can start sending your commands to the server using SOCKET descriptor, otherwise your cpent will come out by giving an error message.

Cpent - Server Example

Following is a Perl code to implement a simple cpent-server program using Perl socket. Here server pstens for incoming requests and once connection is estabpshed, it simply reppes Smile from the server. The cpent reads that message and print on the screen. Let s see how it has been done, assuming we have our server and cpent on the same machine.

Script to Create a Server

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

use strict;
use Socket;

# use port 7890 as default
my $port = shift || 7890;
my $proto = getprotobyname( tcp );
my $server = "localhost";  # Host IP running the server

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

# bind to a port, then psten
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "Can t bind to port $port! 
";

psten(SOCKET, 5) or die "psten: $!";
print "SERVER started on port $port
";

# accepting a connection
my $cpent_addr;
while ($cpent_addr = accept(NEW_SOCKET, SOCKET)) {
   # send them a message, close connection
   my $name = gethostbyaddr($cpent_addr, AF_INET );
   print NEW_SOCKET "Smile from the server";
   print "Connection recieved from $name
";
   close NEW_SOCKET;
}

To run the server in background mode issue the following command on Unix prompt −

$perl sever.pl&

Script to Create a Cpent

!/usr/bin/perl -w
# Filename : cpent.pl

use strict;
use Socket;

# initiapze host and port
my $host = shift ||  localhost ;
my $port = shift || 7890;
my $server = "localhost";  # Host IP running the server

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

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

Now let s start our cpent at the command prompt, which will connect to the server and read message sent by the server and displays the same on the screen as follows −

$perl cpent.pl
Smile from the server

NOTE − If you are giving the actual IP address in dot notation, then it is recommended to provide IP address in the same format in both cpent as well as server to avoid any confusion.

Advertisements