Herong's Tutorial Notes on Perl - Part B
Dr. Herong Yang, Version 4.11

Socket Communication

Part:   1  2  3  4  

(Continued from previous part...)

Here is sample program to show you how these functions work:

#- NetworkInfo.pm
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $s = getprotobyname('tcp');
   @l = getprotobyname('tcp');
   print "\ngetprotobyname():\n";
   print "   scalar = ", $s, "\n";
   print "   list = (", join(',',@l), ")\n";
   $s = getservbyname('ftp', 'tcp');
   @l = getservbyname('ftp', 'tcp');
   print "\ngetservbyname():\n";
   print "   scalar = ", $s, "\n";
   print "   list = (", join(',',@l), ")\n";
   $s = getservbyport(23, 'tcp');
   @l = getservbyport(23, 'tcp');
   print "\ngetservbyport():\n";
   print "   scalar = ", $s, "\n";
   print "   list = (", join(',',@l), ")\n";
   $s = gethostbyname('www.perl.org');
   @l = gethostbyname('www.perl.org');
   print "\ngetservbyname():\n";
   print "   scalar = ", $s, "\n";
   print "   list = (", join(',',@l), ")\n";
   $s = gethostbyname('216.109.118.67');
   @l = gethostbyname('216.109.118.67');
   print "\ngetservbyname():\n";
   print "   scalar = ", $s, "\n";
   print "   list = (", join(',',@l), ")\n";
   $domain = 2;
   $s = gethostbyaddr(pack('C4', 216,109,118,67), $domain);
   @l = gethostbyaddr(pack('C4', 216,109,118,67), $domain);
   print "\ngethostbyaddr():\n";
   print "   scalar = ", $s, "\n";
   print "   list = (", join(',',@l), ")\n";
   exit;

Output:

getprotobyname():
   scalar = 6
   list = (tcp,TCP,6)

getservbyname():
   scalar = 21
   list = (ftp,,21,tcp)

getservbyport():
   scalar = telnet
   list = (telnet,,23,tcp)

getservbyname():
   scalar = ?v  
   list = (x2.develooper.com,www.perl.org,2,4,?v  )

getservbyname():
   scalar = +mvC
   list = (216.109.118.67,,2,4,+mvC)

gethostbyaddr():
   scalar = p4.www.dcn.yahoo.com
   list = (p4.www.dcn.yahoo.com,,2,4,+mvC)

Socket Module

In the previous examples, there are a lots hard coded values, like socket domain and socket type. The Socket Module is designed to help you to hide those values. It also offers a number of methods to pack and unpack IP addresses and socket addresses.

PF_INET - Returns the socket domain number of Internet domain.

SOCK_STREAM - Returns the socket type number for sequenced, reliable, two-way connection, byte streams

INADDR_ANY - Returns the packed wildcard IP address, similar to pack('C4', 0,0,0,0).

inet_aton("216.109.118.67") - Returns the packed form of the specified IP address, similar to pack('C4', 216,109,118,67). inet_aton("www.yahoo.com") works too.

inet_aton($pHost) - Returns the unpacked form of the specified packed IP address.

pack_sockaddr_in($port, $pHost) - Returns the packed socket address of the specified port number and packed IP address. Internet domain number will be automactically added. This function is similar to pack('S n a4 x8', $domain, $port, $pHost);

unpack_sockaddr_in($address) - Returns port name and packed IP address in an array of the specified packed socket address.

sockaddr_in($port, $pHost) - Same as pack_sockaddr_in($port, $pHost) in scalar context.

sockaddr_in($address) - Same as unpack_sockaddr_in($address) in list context.

I revised the Reverse Echoer server application with the help of Socket Module:

#- ReverseEchoer2.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   use Socket;
   $proto = getprotobyname('tcp');
   socket(SOCK,PF_INET,SOCK_STREAM,$proto);
   $host = INADDR_ANY;
   $port = 8888;
   $address = pack_sockaddr_in($port, $host);
   bind(SOCK, $address);
   $queueSize = 5; # Queue up to 5 connections
   listen(SOCK, $queueSize);
   $hostName = inet_ntoa($host);
   print STDOUT "Server host: $hostName\n";
   print STDOUT "Server port: $port\n";
   $cAddress = accept(NEWSOCK,SOCK);
   ($cPort, $cHost) = unpack_sockaddr_in($cAddress);
   $cHostName = inet_ntoa($cHost);
   print STDOUT "Client host: $cHostName\n";
   print STDOUT "Client port: $cPort\n";
   select(NEWSOCK); $| = 1; select(STDOUT);
   print NEWSOCK "Welcome to Reverse Echo Server.\r\n";
   while ($m=<NEWSOCK>) {
      $m =~ s/\n|\r//g;
      last if ($m eq ".");
      $m = reverse($m);
      print NEWSOCK "$m\r\n";
   }
   close(NEWSOCK);
   exit;

Part:   1  2  3  4  

Dr. Herong Yang, updated in 2006
Herong's Tutorial Notes on Perl - Part B - Socket Communication