原创 Socket Programming in PERL

2009-5-26 23:55 2530 4 4 分类: 工程师职场


2007年07月26日 星期四 09:04


Part
1:
Socket
Programming in PERL


Inthis article, Rahul shows us
how to create a client-server socketprogram in Perl and then demonstrates it by
pinging the server.

Whatis a socket? Just another bit of computer jargon? Devling a little
intonetworking history, it is a Berkeley UNIX mechanism of creating avirtual
duplex connection between processes. This was later ported onto every known OS
enabling communication between systems acrossgeographical location running on
different OS software. If not for thesocket, most of the network communication
between systems would neverever have happened.

Taking a closer look; a
typical computersystem on a network receives and sends information as desired by
thevarious applications running on it. This information is routed to thesystem,
since a unique IP address is designated to it. On the system,this information is
given to the relevant applications which listen ondifferent ports. For example a
net browser listens on port 80 forinformation. Also we can write applications
which listen and sendinformation on a specific port number.

For now,
let's sum up that a socket is an IP address and a port, enabling
connection.


Part 2:Types of
Sockets


There are just two types of sockets:
connectionoriented and connection-less. There are other types but
thisclassification is fair enough to get started, a socket has a domain
(
UNIX or internet), a connection type (connection
oriented or connection less) and a protocol (TCP or UDP).


A connection oriented or a stream socket is a
reliable two way
communication.If you send three packets, say 1, 2 and 3, they are
received in thesame order they were sent. They achieve this high level of
transmissionquality by using TCP for error free reliable communication.
Theubiquitous telnet application uses stream sockets.


Theconnection-less sockets or stream-less sockets
use IP for routing butuse the UDP. They are connectionless, since the connection
need not beopen as in stream sockets, the packet formed is given a destination
IPaddress and than transmitted. This method is mostly used forpacket-to-packet
transfer as in ftp applications.


How a Packet is Formed

We will use an
example of UDP packet for some light stuff on
networkingtheory. It's Data Encapsulation. A packet is formed
by encapsulatingthe data in a header at each level as it passes through the
layers(protocol stack). At the receiving end the headers are stripped off asthe
packet travels up the layers to get the data.


Basically, at each layer, the protocol adds a header
to the payload to perform the required functionality.

Client Server
Architecture


It's a client-server world, today. Just about
everything on the network deals with client processes talking to
serverprocesses and vice versa. Take the ubiquitous
telnet, for instance.When you connect to a remote host on port 23 with telnet
(the client),a program on that host (called telnetd, the server) springs to
life. Ithandles the incoming telnet connection, sets up a login prompt, etc.Note
that the client-server pair can speak in streaming or stream-less,or anything
else (as long as they are speaking the same thing).

Some good examples of client-server pairs are
telnet/telnetd, ftp/ftpd.



Part
3:
Client–Server
Script in PERL


Comfortable so far? Let's dive head-first in tocoding a simple client
server interaction in PERL. Client/servernetwork programming requires a server
running on one machine to serveone or more clients running on either the same
machine or differentmachines. These different machines can be located anywhere
on thenetwork.

To create a server, simply perform the following steps
using the built-in Perl function indicated:

  1. Create a socket with socket.
  2. Bind the socket to a port address with bind.
  3. Listen to the socket at the port address with listen.
  4. Accept client connections with accept.
Establishing a client is
even easier:

  1. Create a socket with socket.
  2. Connect (the socket) to the remote machine with connect.
A Simple
Server

1. #! /usr/bin/perl -w
2. # server0.pl

3. #--------------------

4. use strict;
5. use Socket;


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

9. # create a socket, make it reusable

10. socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";

11. setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1) or die "setsock: $!";


12. # grab a port on this machine
13. my $paddr = sockaddr_in($port,
INADDR_ANY);

14. # bind to a port, then listen
15. bind(SERVER,
$paddr) or die "bind: $!";
16. listen(SERVER, SOMAXCONN) or die "listen:
$!";
17. print "SERVER started on port $port ";

18. # accepting a
connection
19. my $client_addr;
20. while ($client_addr = accept(CLIENT,
SERVER))
21. {
22. # find out who connected
23. my ($client_port,
$client_ip) = sockaddr_in($client_addr);
24. my $client_ipnum =
inet_ntoa($client_ip);
25. my $client_host = gethostbyaddr($client_ip,
AF_INET);
26. # print who has connected
27. print "got a connection
from: $client_host","[$client_ipnum] ";
28. # send them a message, close
connection
29. print CLIENT "Smile from the server";
30. close CLIENT;

31. }


Analysis

Thissimple server can run
just on one machine that can service only oneclient program at a time connecting
from the same or a differentmachine. Recall that the steps for creating a server
were to create asocket, bind it to a port, listen at the port and accept
clientconnections.

Line 1 and 4
It is generally a goodidea to
compile a Perl script using strict. This requires all variablesto be declared
with the "my" function before they are used. Using "my"may be inconvenient, but
it can catch many common syntactically correctyet logically incorrect
programming bugs.

Line 7
Thevariable $port is assigned the
first command-line argument or port 7890as the default. When choosing a port for
your server, pick one that isunused on your machine.

Line 10 and
11

The socketis created using the socket function. A socket is like a
file handle-itcan be read from, written to or both. The function setsockopt is
calledto ensure that the port will be immediately reusable.

Line
13

Thesockaddr_in function obtains a port on the server. The
argumentINADDR_ANY chooses one of the server's virtual IP addresses. You
couldinstead decide to bind only one of the virtual IP addresses byreplacing
INADDR_ANY with inet_aton("192.168.1.1") or gethostbyname('localhost')


Line 15
The bind function binds the socket to the port, i.e.,
plugs the socket into that port.

Line 16
Thelisten function
causes the server to begin listening at the port. Thesecond argument to the
listen function is the maximum queue length orthe maximum number of pending
client connections. The value SOMAXCONNis the maximum queue length for the
machine being used.

Line 20
Oncethe server begins listening
at the port, it can accept clientconnections using the accept function. When the
client is accepted, anew socket is created named CLIENT which can be used like a
filehandle. Reading from the socket reads the client's output and printingto the
socket sends data to the client. The return value of the acceptfunction is the
Internet address of the client in a packed format.

Line 24 and 25

Thefunction sockaddr_in takes the packed format and returns the client'sport
number and the client's numeric Internet address in a packedformat. The packed
numeric Internet address can be converted to a textstring representing the
numeric IP using inet_ntoa (numeric to ASCII).To convert the packed numeric
address to a host name, the functiongethostbyaddr is used.

Start the
script on a localhost. I ranthese scripts on a Windows 2000 machine with Active
PERL ( binary build631 PERL v5.6.1). The output looks something like this.


D:GalantPerl>start server1.pl
SERVER started
on port 7890


The server is now listening at port 7890 on the
local host, waiting for clients to connect.

A Simple Client


1. #! /usr/bin/perl -w
2. # client1.pl - a
simple client
3. #----------------

4. use strict;
5. use Socket;


6. # initialize host and port
7. my $host = shift || 'localhost';

8. my $port = shift || 7890;

9. my $proto = getprotobyname('tcp');


10. # get the port address
11. my $iaddr = inet_aton($host);
12.
my $paddr = sockaddr_in($port, $iaddr);
13. # create the socket, connect to
the port
14. socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
a. or die
"socket: $!";
15. connect(SOCKET, $paddr) or die "connect: $!";

16.
my $line;
17. while ($line = )
18. {
19. print $line;

20. }
21. close SOCKET or die "close: $!";



Analysis

Line 7 and 8
Takesthe command-line
arguments of host name and port number or if noarguments are passed initializes
variables with the default values.

Line 11 and 12
The host
name and the port number are used to generate the port address using inet_aton
(ASCII to numeric) and sockaddr_in.

Line 14 and 15
A socket
is created using socket and the client connects the socket to the port address
using connect.

Line 17 and 21
Thewhile loop then reads the
data the server sends to the client until theend-of-file is reached, printing
this input to STDOUT. Then the socketis closed.

Output on the server:


D:GalantPerl>start server1.pl
SERVER started
on port 7890
got a connection from: SHILPA[172.16.0.160]


Output on the client:

C:>\rahulperlclient1.pl rahul
Smile from the
server


part 4:PERL Makes
Life Easy


Those
scripts were a lot of PERL code just to send afew bytes of information across.
It is possible to write some cute andshort socket programs by using OO Concepts
and the IO::Socket module.We shall see now, how it is possible.

Sample
Script Server Using IO


1. #!/usr/bin/perl -w
2. # serIO.pl
3. #
server using IO::Socket
4. #---------------------
5. use strict;
6.
use IO::Socket;

7. my $sock = new IO::Socket::INET(
LocalHost =>
'localhost',
LocalPort => 7890,
Proto => 'tcp',
Listen
=> SOMAXCONN,
Reuse => 1);

8. $sock or die "no socket :$!";

9. my($new_sock, $c_addr, $buf);

10. while (($new_sock, $c_addr) =
$sock->accept())
11. {
my ($client_port, $c_ip)
=sockaddr_in($c_addr);
my $client_ipnum = inet_ntoa($c_ip);
my
$client_host =gethostbyaddr($c_ip, AF_INET);
print "got a
connection from: $client_host"," [$client_ipnum] ";

while (defined ($buf
= <$new_sock>))
{
print $buf;
}
12. }



Analysis

Line 7
A new IO::Socket::INET
object is created using the new method The new method returns a socket that is
assigned to $sock

Line 10
Aclient connection is accepted
using the accept method. The acceptmethod returns the client socket when
evaluated in scalar context andthe client's socket and IP address when evaluated
in list context.

Sample Client Script Using IO

1. #!/usr/bin/perl -w
2. # cliIO.pl
3. # a simple client
using IO:Socket
4. #----------------

5. use strict;
6. use
IO::Socket;

7. my $host = shift ||
'localhost';
8. my $port = shift || 7890;
9. my $sock = new
IO::Socket::INET( PeerAddr => $host, PeerPort => $port, Proto =>
'tcp');
10. $sock or die "no socket :$!";
11. foreach my $i (1..10)

12. {
13. print $sock "$i",scalar(localtime)," ";
14. sleep(1);

15. }
16. close $sock;


Analysis

A new
object is created which connects to the server and sends 10 timestamp strings
with 1 second delay in between.

Output of the new cute scripts:


D:GalantPerl>start perl serIO.pl

D:GalantPerl>cliIO.pl


On the server window:

got a connection from: RAHUL [127.0.0.1]
1Thu Feb 6 12:52:57
2003
2Thu Feb 6 12:52:58 2003
3Thu Feb 6 12:52:59 2003
4Thu Feb 6
12:53:00 2003
5Thu Feb 6 12:53:01 2003
6Thu Feb 6 12:53:02 2003
7Thu
Feb 6 12:53:03 2003
8Thu Feb 6 12:53:04 2003
9Thu Feb 6 12:53:05 2003

10Thu Feb 6 12:53:06 2003


Pinging
in PERL


Perl makes life easy, with it various modules available.
Let's demonstrate this by writing a short and quick ping program.

Sample
Ping Program

1. #!/usr/bin/perl
2. # ping.pl

3. # a simple ping program
4. #---------------

5. use Net::Ping;


6. $pinghost = shift||"gsmgprs";
7. print "Pinging $pinghost ";


8. $p = Net::Ping->new("icmp", 2);

9. for (;;) # infinite
loop
10. {
11. unless ($p->ping($pinghost))
12. {
13. print
"Fail: ", scalar(localtime), " ";
14. } else
15. {
16. print
"Success: ", scalar(localtime), " ";
17. }
18. sleep 10;
19.
}


Analysis

TheNet::Ping makes pinging remote
hosts easy and quick. An object of theclass created. Here we use the icmp
protocol (you can also choose tcpor udp).

A sample output:

D:GalantPerl>ping.pl
Pinging gsmgprs
Success: Thu Feb
6 14:22:01 2003
Success: Thu Feb 6 14:22:11 2003
Success: Thu Feb 6
14:22:21 2003
Success: Thu Feb 6 14:22:31 2003
Success: Thu Feb 6
14:22:41 2003
Success: Thu Feb 6 14:22:51 2003
Success: Thu Feb 6
14:23:01 2003
Success: Thu Feb 6 14:23:11 2003
Success: Thu Feb 6
14:23:21 2003
Success: Thu Feb 6 14:23:31 2003


part 5:Conclusion


Perl is a powerful, easy to learn, widely accepted
and supported language. The freely available
modules on CPAN (including the modules for network programming)
cater to all development
needs.


来源:不详

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条