Easy Tutorial
❮ Perl Directories Perl Hashes ❯

Perl Socket Programming

Socket, also known as "socket", is typically used by applications to send requests to the network or respond to network requests, enabling communication between hosts or processes on a single computer.

This section introduces how to use Socket services in Perl.


Creating a Server

-

Use the socket function to create a socket service.

-

Use the bind function to bind to a port.

-

Use the listen function to listen on a port.

-

Use the accept function to receive client requests.

Creating a Client

-

Use the socket function to create a socket service.

-

Use the connect function to connect to the server socket.

The following diagram demonstrates the communication flow between the client and the server:


Server Socket Functions

socket Function

In Perl, we use the socket() function to create a socket with the following syntax:

socket( SOCKET, DOMAIN, TYPE, PROTOCOL );

Parameter explanation:

-

DOMAIN specifies the protocol family for the created socket. For example:

-

TYPE specifies the socket type, which can be either connection-oriented (SOCK_STREAM) or connectionless (SOCK_DGRAM)

-

PROTOCOL should be (getprotobyname('tcp'))[2]. It specifies the actual transport protocol used.

Thus, the socket function call looks like this:

use Socket     # Defines PF_INET and SOCK_STREAM

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

bind() Function

Use bind() to assign an address to a socket:

bind( SOCKET, ADDRESS );

SOCKET is a socket descriptor. ADDRESS is the socket address (TCP/IP) which includes three elements:

-

Address family (TCP/IP, which is AF_INET, possibly 2 on your system)

-

Port number (e.g., 21)

-

Network address (e.g., 10.12.12.168)

After creating a socket with socket(), it is only assigned a protocol and not an address. Before accepting connections from other hosts, you must call bind() to assign an address to the socket.

Here is a simple example:

use Socket        # Defines PF_INET and SOCK_STREAM

$port = 12345;    # Port to listen on
$server_ip_address = "10.12.12.168";
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
   or die "Cannot bind port! \n";

or die executes if the address binding fails.

By setting the setsockopt() option SO_REUSEADDR, the port can be reused immediately.

The packsockaddrin() function converts the address to binary format.

listen() Function

After a socket is bound to an address, the listen() function starts listening for possible connection requests. However, this can only be used when reliable data stream is guaranteed:

listen( SOCKET, QUEUESIZE );

SOCKET: A socket descriptor.

QUEUESIZE: An integer that determines the size of the listening queue. When a connection request arrives, it enters this queue; when a connection request is accepted by accept(), it is removed from the queue; when the queue is full, new connection requests return an error.

Upon accepting a connection, it returns 0 for success and -1 for error.

accept() Function

The accept() function accepts a connection request to the socket. It returns the compressed form of the network address if successful, otherwise FALSE:

accept( NEW_SOCKET, SOCKET );

NEW_SOCKET: A socket descriptor.

SOCKET: A socket descriptor.

accept() is typically used in an infinite loop:

while(1) {
   accept( NEW_SOCKET, SOCKT );
   .......
}

This example continuously listens for client requests.


Client Functions

connect() Function

The connect() system call establishes a connection for a socket, with parameters including the file descriptor and host address.

connect( SOCKET, ADDRESS );

Here is an example of creating a connection to a server socket:

$port = 21;    # ftp port

connect( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
   or die "Cannot connect to server! \n";
$server_ip_address = "10.12.12.168";
connect(SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
    or die "Unable to bind to port! \n";

Complete Example

Next, we will go through a complete example to understand the application of all socket functions:

Server-side server.pl code:

Example

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

use strict;
use Socket;

# Use port 7890 as the default
my $port = shift || 7890;
my $proto = getprotobyname('tcp');
my $server = "localhost";  # Set local address

# Create socket, port reusable, create multiple connections
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
   or die "Unable to open socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
   or die "Unable to set SO_REUSEADDR $!\n";

# Bind port and listen
bind(SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "Unable to bind to port $port! \n";

listen(SOCKET, 5) or die "listen: $!";
print "Server started on port: $port\n";

# Accept requests
my $client_addr;
while ($client_addr = accept(NEW_SOCKET, SOCKET)) {
   # Send a message, close connection
   my $name = gethostbyaddr($client_addr, AF_INET);
   print NEW_SOCKET "This is a message from the server";
   print "Connection received from $name\n";
   close NEW_SOCKET;
}

Open a terminal and execute the following code:

$ perl server.pl
Server started on port: 7890

Client-side client.pl code:

Example

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

use strict;
use Socket;

# Initialize address and port
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "localhost";  # Host address

# Create socket and connect
socket(SOCKET, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2])
   or die "Unable to create socket $!\n";
connect(SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "Unable to connect to port $port! \n";

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

Open another terminal and execute the following code:

$ perl client.pl
This is a message from the server
❮ Perl Directories Perl Hashes ❯