|
[A Newbies Guide To Sockets in PERL]===================================[Beowulf] Some of this was taken from "PERL in a nutshell" by Oriely. (and then modified by me) I'm assuming you have programed in PERL before or maybe just a little bit because this is not a newbies guide to PERL but to sockets in PERL. So a small background in the language would be nice. This paper will contain a quick introduction to sockets, programing only the client side. (Because im too lazy to do server side) If you really want to make it easy, using the IO::Socket module, at the end will be a quick little script that tests ports to see if they are open from the client side. Feel free to modify it because its pretty lazy coding, but it was late and I didnt have a lot of time so change it. Anyways if you have any questions, email me at chixdigUNIX@the-pentagon.com or talk to me on irc undernet under the name beowulf. On with the tutorial! First off you need to know what a socket does... I took this definition right from one of oriely's book so dont get mad at me if you dont like it... "Sockets are the underlying mechanism for networking on the Internet. With sockets, one application (a server) sits on a port waiting for connections. Another application (the client) connects to that port and says hello; then the client and server have a chat. Their actual conversation is done with whatever protocol they choose - for example, a web client and server would use HTTP, an email server would use POP3 and SMTP, etc. But at the most basic level, you might say that all network programming comes down to opening a socket, reading and writing data, and closing the socket again. Sockets provide a connection between systems or applications. They can be set up to handle streaming data or discrete data packets. Streaming data continually comes and goes over a connection. A transport protocol like TCP (Transmission Control Protocol) is used to process streaming data so that all of the data is properly received and ordered. Packet-oriented communication sends data across the network in discrete chunks. The message-oriented protocol UDP (User Datagram Protocol) works on this type of connection. Although streaming sockets using TCP are widely used for applications, UDP sockets also have their uses. Sockets exist in one of two address domains: the Internet domain and the Unix domain. Sockets that are used for Internet connections require the careful binding and assignment of the proper type of address dictated by the Internet Protocol (IP). These sockets are referred to as Internet-domain sockets. Sockets in the Unix domain create connections between applications either on the same machine or within a LAN. The addressing scheme is less complicated, often just providing the name of the target process." Socket Functions in PERL socket - Set up a socket and assign a filehandle to it connect - Client side only: you guessed it it connects to a socket recv - Reads data from a filehandle send - Writes data to a filehandle shutdown - Terminates a connection How to set up a socket: You need several arguments before you can set up a socket such as... either PF_INET if you want to connect to a internet address or PF_UNIX if you are connecting to a UNIX domain address. Next you need to set up the argument for what type of connection you want to establish. If you want to have a packet-based UDP connection you would use SOCK_DGRAM, or if you want a streaming TCP connection you would use SOCK_STREAM, The next argument would be the protocol you want to use for the connection, you would use getprotobyname for this.. And for the last argument your going to want that handy die command with the error variable $!. So lets look at a typical way to set up a socket... use Socket; socket (BLAH, PF_UNIX, SOCK_STREAM, getprotobyname('tcp')) || die $!; Ok lets take a look at the arguments used...The BLAH would be the sockets filehandle. The PF_UNIX would set up sockets for a Unix domain address, the SOCK_STREAM would specify the streaming TCP connection, the getprotobyname sets the protocol to be TCP and then, of course, you have the die command. Client Side Programing: For a client side program after you set up the socket you need to connect to a specific port with the connect command. Again you need arguments the first being the socket filehandle and the second being the data structure. You will also need either the sockaddr_un for Unix domain addresses and sockaddr_in function for internet addresses. If you want to use sockaddr_in you need more arguments, the first is the port number, the second is a ip address or a URL. So lets say you want to connect to port 21 on the server blah.com it would look something like this: my $variable = sockaddr_in (21, inet_aton('blah.com')); connect (KFL, $variable) || die $!; If it does connect it will return a true value (i.e. 1)if it doesnt it will display the error message with the $! variable. If it does connect you can do a number of things such as the send command which sends data to the host or the recv command to read incoming data on the socket. After you are done using the socket you'll want to shut it down with the close or shutdown command. The IO::socket module: The IO::socket module is included in the core of perl and it makes life easier for all you lazy programers. Instead of using the above method, using this module makes it more object oriented. Here is an example on how to set up a socket: use IO::Socket; $blah = new IO::Socket::INET (PeerAddr => 'X.X.X.X', PeerPort => 23, Proto => 'tcp'); die "$!" unless $blah Ok you can pretty much figure it out yourself where X.X.X.X is the ip or host name of the server. PeerPort is obviously the port you want to connect to and the proto is the protocol you want to use. There are other functions of the IO::socket module but im too lazy to write them all out you can get more info on them at cpan.org Example of a badly written program without using the IO::socket module to test ports: #!/usr/bin/perl use Socket; socket (BLAH, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die $!; print "Please enter the host you want to test\n"; chomp($host = <STDIN>); print "please enter a port\n"; chomp($port = <STDIN>); my $blah = sockaddr_in ($port, inet_aton("$host")); connect (BLAH, $blah) || die $!; if ($blah) { print "Port found\n"; } else { print "Port not found for reason... $!\n"; } ok and now for one with the IO::socket module: #!/usr/bin/perl use IO::Socket; print "Please enter the host you want to test\n"; chomp($host = <STDIN>); print "please enter a port\n"; chomp($port = <STDIN>); $blah = new IO::Socket::INET (PeerAddr => "$host", PeerPort => $port, Proto => 'tcp'); if ($blah) { print "Port found\n"; } else { print "Port not found for reason... $!\n"; } Ok well thats it for the time being if this makes it into KV then I will write up another paper this time on the server side. Hi to everyone i know on irc later for now, beowulf