Perl - Socket Programming

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 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 an internet browser listens on port 80 for information received from the web server. Also we can write our custom applications which may listen 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, enabling connection to send and recieve data over a network.

To explain above mentioned socket concept we will take an example of Client - Server Programming using Perl. To complete a client 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 listen call.

Accept client connections using accept call.

To Create a Client

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 Client and Server to communicate with each other −

Server Side Socket Calls

The socket() call

The socket() call is the first call in establishing 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 like 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 clients.

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 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 listen() call

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

listen( 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 client 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 listen 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 client.

Client Side Socket Calls

The connect() call

If you are going to prepare client 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 client and ADDRESS is a socket address similar to bind call, except that it contains the IP address of the remote server.

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

Client - Server Example

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