     
                                                     
                                                       
               ۰߰     ܰ۰  
             ۱      ܱ߰    ۰
             ۱          ۱      ۰  
                 ܰ߱    ߰۲    
              Outbreak Magazine Issue #14 - Article 2 of 15
          '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

Art of Perl v2.0 
================
By buffer


   This issue will mostly deal with socket's, and how to create a simple
IRC bot. A socket is just a wormhole for talking to computers across networks.
Two of the main protocol's used to communicate across socket's are TCP and
UDP. TCP stands for the Transmission Control Protocol. It uses a retransmission
strategy to insure that data will not be lost. UDP stands for the User Datagram
Protocol, which is a connectionless protocol, Meaning, It sends the packet's 
without knowing if the other socket is ready. It doesn't care. It is faster than
TCP but not as reliable. Perl interfaces with these protocols very well. We'll
be using the TCP protocol throughout the issue, using the IO::Socket module in
Perl.

  If you use a UNIX based system, a socket is just a file descriptor. As, is 
everything in UNIX pretty much. All the hardware is accessed through device
files. Which hold's true to the "Everything in Unix is a file" standard.
But with Perl, even if you're on a different system. It will work fine. To create
A socket in Perl, you do as so:

Use IO::Socket; # puts the IO::Socket module into play. 

my $sock = IO::Socket::INET->new(PeerAddr => "$addr",

			         PeerPort => "$port",

				 Proto => 'tcp');


   Of course the variables will have to have the correct values. So now we have
a socket descriptor, the communicate through to the peer host. $sock. You can
write to it with a plain:

print $sock("Hello Dingo.\n\r"); 


   Which is all fine and dandy, but a more reliable method is to use the 
send() function. It provides a cleaner way. And flushes the socket automatically
to make sure there is no data left behind. Example:

$sock->send("all yur base belong to us\n\r"); 


   Simple enough? Just put the sock descriptor, in our case $sock referenced 
to the send() function using the -> operator. To make sure we had no errors 
on connect we should add a die() like so: 

my $sock = IO::Socket::INET->new(PeerAddr => "$addr",

			         PeerPort => "$port",

				 Proto => 'tcp') or die("connect error\n");



  Another useful thing about Perl, is that it has special variables. One we 
could use here, is the $! variable, which contains the error message from the
operating system, so in our die() we could do something like:

die("Connect error: $!\n"); # which will contain a more verbose error. 


  If you want to check out all of perl's variables check out perldoc perlvar.
Which lists them all. Or go to www.perldoc.org. Perldoc comes standard with
Perl. Now to the IRC stuff. The IRC protocol isn't too difficult to grasp. 
I won't really explain the gritty details, cause it should be clear in the code.
If you really want the technical details. Read the IRC RFC. When we connect to 
an IRC server we need to send the USER command, followed by the NICK command. 
USER takes four arguments. NICK takes one of course. We'll just show the 
connecting part thus far:

my $server = "irc.freenode.net"; # replace with whichever server

my $port = "6667"; # Usually the standard with IRC servers. 

my $nick = "dingo"; # enough said. 

my $user = "dingo dingo dingo dingo"; # just giving it four arguments so the 
server won't complain.



my $sock = IO::Socket::INET->new(PeerAddr => "$server",

			         PeerPort => "$port",

				 Proto => 'tcp') or die("Error: $!);



login(); # branches off into the login function.



while(defined($buffer = <$sock>)) {  # will explain later.

print $buffer;

}



sub login {

$sock->send("USER $user\n\r"); # send the server our user info

$sock->send("NICK $nick\n\r"); # and our nick;

return; # return to main.

}





  And your connected to the server. I used a line up above:



while(defined($buffer = <$sock>)) {

print $buffer;

}



  What this does, is assign all the received data from the socket into $buffer. 
So we can see what the server is spitting out at us, and if our login was 
successful. It says, while the socket is active assign all of the given output 
from the server into $buffer. If the socket wasn't active it wouldn't enter
the while(). The defined() just check's to see if the given arguments return 
true. It's not too difficult to connect to a server. This bot isn't gonna be an 
elegant full fledged creature. It's just to show you how to connect to and 
communicate across sockets with Perl. Hopefully it's easy enough for you. I'll 
leave it off with the final example. We'll join a room. And print all the 
conversation going on. Then it will be a good start for you to add functionality
if you want. Here goes:



use IO::Socket;

my $server = "irc.freenode.net";

my $port = 6667; 

my $nick = "dingo"; 

my $user = "dingo dingo dingo dingo";

my $buffer; 

my $room = "#room";

my $sock = IO::Socket::INET->new(PeerAddr => "$server",

                                 PeerPort => "$port",

                                 Proto => 'tcp') || die("error: $!\n");



login();

print("Login successful, continuing on..\n");

joinrm();

while(defined($buffer = <$sock>)) {



print ("Received: $buffer\n");



if($sock =~ /PING/i) { 

	  

          print("Received PING from server.. ponging..\n");

	  $sock->send("PONG $server\n\r"); 

   }



}



sub login {

    

    $sock->send("USER $user\n\r");	

    $sock->send("NICK $nick\n\r");

    return;



}



sub joinrm {

    $sock->send("JOIN $room\n\r");

    return;

}



    That's that. That should keep you alive. The line if($sock =~ /PING/i) { .. }
responds to the server's ping's, if you don't you'll be disconnected with a 
Ping timeout error. To msg a room you can add: 

$sock->send("PRIVMSG #room:$message\n\r");  

Hopefully you have a better understanding of socket's and have an idea how 
to interact with them through Perl. Email me with any question's, comment's, 
insults. Peace. 


				     buffer

		                  AIM:buffer18

               	          Email:buffer@uncompiled.com
