Perl

42
Perl Server side networking and modules

description

Server side networking and modules. Perl. Server Side networking. Uses same modules. Instead connection to something, the server side will listen for the incoming connection. IO::Socket Server. - PowerPoint PPT Presentation

Transcript of Perl

Page 1: Perl

Perl

Server side networking and modules

Page 2: Perl

Server Side networking

• Uses same modules.—Instead connection to something, the server

side will listen for the incoming connection.

Page 3: Perl

IO::Socket Server

$server = IO::Socket::INET->new (LocalPort =>$server_port, Type => SOCK_STREAM, Reuse=> 1, Listen => 10)

or die "Couldn't open port $server_port: $@\n";—LocalPort => $server_port

– Where $server_port is the port number the server will use

—Reuse => 1– Reuse the port, so the server can reuse the port,

instead of waiting two minutes for the O/S to release the port

—Listen =>10– Where 10 is the number O/S how many unanswered

connections to queue up waiting for you server. SOMAXCONN is the max connection the O/S will allow.

Page 4: Perl

IO::Socket Server (2)

• Now the server waits for a connection• Use the accept function$client = $server->accept();

• After the client connection is established use $client like FILEHANDLE

• to close the server sideclose $client; #disconnect client from serverclose $server; #close server connection

Page 5: Perl

IO::Socket Server Example#!/usr/bin/perluse IO::Socket;

$server_port = 3012;$server = IO::Socket::INET->new (LocalPort => $server_port, Type => SOCK_STREAM, Reuse=> 1, Listen => 10)

or die "Couldn't open port $server_port: $@\n";

$client = $server->accept(); $line = <$client>;print "$line \n";print $client "Hi back \n";close $client; close $server;

Page 6: Perl

IO::Socket Server Example (client side)#!/usr/bin/perluse IO::Socket;$remote_host = "localhost";$remote_port = "3012";$socket = IO::Socket::INET->new (PeerAddr => $remote_host, PeerPort => $remote_port, Proto => "tcp", Type => SOCK_STREAM) or die "Couldn't connect to $remove_host:$remote_port : $@\n";

print $socket "Hi\n"; $answer = <$socket>;print "$answer \n";close $socket;

Page 7: Perl

IO::Socket Server Example for multiple connections#!/usr/bin/perluse IO::Socket;

$server_port = 3012;$server = IO::Socket::INET->new (LocalPort =>

$server_port, Type => SOCK_STREAM, Reuse=> 1, Listen => 10)

or die "Couldn't open port $server_port: $@\n";

while($client = $server->accept() ) {#answer each connection, then disconnects clients,

and answers next connection$line = <$client>;print "$line \n";print $client "Hi back \n";close $client;

}close $server;

Page 8: Perl

Socket Server

• Again more complex and multi stepped.• create a socket to usesocket(SERVER, PF_INET, SOCK_STREAM,

getprotobyname('tcp'));—SERVER is the HANDLE—PF_INET the domain type, with IO::Socket it was part of

the new call.—getprotobyname('tcp') get the O/S number for tcp

– should allows use this function, since the number has been known to change and for portability issues.

—NOTE: should allows use the constants, instead of the number equivalent, because these number have been known to change (on a whim) and portability between versions of the same O/S become an issue.

Page 9: Perl

Socket Server(2)

• Setup the Reuse partsetsockopt (SERVER, SOL_SOCKET, SO_REUSEADDR, 1);

• Next build up my socket address$my_addr = sockaddr_in($server_port,

INADDR_ANY);—INADDR_ANY allows clients to from anywhere

• Next bind to the socketbind(SERVER, $my_addr);• Establish listen queue for connectionslisten(SERVER, SOMAXCONN);

—SOMAXCONN is the max connection allowed in queue, before I used 10.

Page 10: Perl

Socket Server(3)

• Now wait for a connectionaccept(CLIENT, SERVER);

• Use CLIENT as the FILEHANDLE

• close server connectionclose SERVER;

Page 11: Perl

Socket Server example#!/usr/bin/perluse Socket;use IO::Handle;

$remote_port = 3012;socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));SERVER->autoflush(1); #socket doesn't have autoflush turned on.setsockopt (SERVER, SOL_SOCKET, SO_REUSEADDR, 1);

$my_addr = sockaddr_in($remote_port, INADDR_ANY);bind (SERVER, $my_addr) or die "can't bind$!\n";

listen(SERVER, SOMAXCONN) or die "Can't listen to port $! \n";

accept (CLIENT, SERVER);CLIENT->autoflush(1); #socket doesn't have autoflush turned on.

$answer = <CLIENT>;print "$answer \n";print CLIENT "Hi back \n";close CLIENT;close SERVER;

Page 12: Perl

Socket Server example client side#/usr/bin/perluse Socket;use IO::Handle;

$remote_host = "localhost";$remote_port = 3012;socket(SERVER, PF_INET, SOCK_STREAM,

getprotobyname('tcp'));SERVER->autoflush(1); #socket doesn't have autoflush

turned on.$internet_addr = inet_aton($remote_host) or die "Can't

convert $!\n"; $paddr = sockaddr_in($remote_port, $internet_addr);print "Attempting to connect :$paddr:\n";connect (SERVER, $paddr) or die "can't connect $!\n";

print SERVER "Hi\n"; $answer = <SERVER>;print "$answer \n";close SERVER;

Page 13: Perl

Socket Server for multiple connections#!/usr/bin/perluse Socket;use IO::Handle;

$remote_port = 3012;socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));SERVER->autoflush(1); #socket doesn't have autoflush turned on.setsockopt (SERVER, SOL_SOCKET, SO_REUSEADDR, 1);

$my_addr = sockaddr_in($remote_port, INADDR_ANY);bind (SERVER, $my_addr) or die "can't bind$!\n";

listen(SERVER, SOMAXCONN) or die "Can't listen to port $! \n";

while (accept (CLIENT, SERVER)) { CLIENT->autoflush(1); #socket doesn't have autoflush turned on. $answer = <CLIENT>; print "$answer \n"; print CLIENT "Hi back \n"; close CLIENT;}close SERVER;

Page 14: Perl

Exercise 14

• Create a server. It should connect and than wait for a message "Connection from NAME"

• It should then response "Hi NAME"

• Listen on port 3012

• Change your client process to connect to localhost, to test your server. (you'll need two dos windows. One for the server, one for the client.

Page 15: Perl

read and sysread

• When you need to read only a specified number bytes, you can use read or sysread, instead of <HANDLE>.

number of bytes read = sysread HANDLE, SCALAR, LENGTHnumber of bytes read = read HANDLE, SCALAR, LENGTH

—basically the same function

—NOTE: ignores all end of line markers, and read the number bytes listed or until "end of file"

• $x = read SERVER, $answer, 100—read from SERVER handle, place 100 bytes of

data into $answer. $x contains number of bytes read.

Page 16: Perl

read example#/usr/bin/perluse Socket;use IO::Handle;

$remote_host = "k2.cs.uwyo.edu";$remote_port = 80;socket(Server, PF_INET, SOCK_STREAM, getprotobyname('tcp'));Server->autoflush(1); #socket doesn't have autoflush turned on.$internet_addr = inet_aton($remote_host) or die "no convert $!\n"; $paddr = sockaddr_in($remote_port, $internet_addr);connect (Server, $paddr) or die "can't connect $!\n";

print Server "GET / HTTP/1.0\n\n";while ($x = read(Server,$answer,100) ) {

last if $x <100; print "$x:Still reading 100 bytes at a time\n";print "$answer\n";

}print "$x: Last line:\n";print "$answer \n";

close Server;

Page 17: Perl

syswrite

• To write a specified number of bytes, you can use syswrite—NOT write, used for formatting. There is no

"opposite" of read.• Number of bytes written = syswrite HANDLE, SCALAR,

LENGTH

• $x = syswrite Server, $line, 25—write 25 bytes of $line to Server. $x contains the

number of bytes actually written—$x can equal 0, if $line is empty.—$x = undef if there was an error.

Page 18: Perl

send and recv functions

• similar to <HANDLE> and print HANDLE• Socket use:

—send(SERVER, $data_to_send, $flags)– send(SERVER, "Hi there\n", 0);

—recv(SERVER, $data_read, $max_len, $flags)– recv(SERVER, $answer, 100, 0);

• IO::Socket use:—$socket->send($data_to_send, $flags)

– $socket->send("Hi there\n", 0);

—$socket->recv($data_read, $flags)– $socket->recv($answer,0);

Page 19: Perl

Server with process concurrency#!/usr/bin/perluse IO::Socket;$server_port = 3012;$server = IO::Socket::INET->new (LocalPort => $server_port, Type

=> SOCK_STREAM, Reuse=> 1, Listen => 10) or die "Couldn't open port $server_port: $@\n";

while($client = $server->accept() ) { if ($pid = fork) { # Parent process next; #go back and accept the next connection } else { unless (defined $pid) {die "Can't fork: $! \n";} #child process $line = <$client>;

print "$line \n"; print $client "Hi back \n"; close $client;

exit; }}close $server;

Page 20: Perl

Closing sockets after forks

• close won't always send the EOF or SIGPIPE after a fork, unless all processes close.

• So, you use shutdown instead.—Socket:—shutdown(SOCKET,0);# I have stopped

reading.—shutdown(SOCKET,1);#I have stopped writing.—shutdown(SOCKET,2);#I have stopped using

this—IO::Socket—$socket->shutdown(0); #stopped reading

– etc…

Page 21: Perl

Modules

• depending on your perl, there may be any number of modules that are built-in. —ActivePerl includes a number of modules that

the standard perl doesn't include. See doc's

• There are thousands of modules can be added to perl—http://www.cpan.org/

– you can find and download modules.

—for ActivePerl– use perl package manager (found on the start menu,

under active perl) once you know what modules you want to install. (see ActivePerl doc's for more help)

+ search <module name> #returns a numbered list of modules matching the queary,

+ install number #where number is from the search list.o Will also install doc into the activePerl doc's

Page 22: Perl

http moduleuse Net::HTTP;my $s = Net::HTTP->new(Host => "asuwlink.uwyo.edu")

|| die $@;

$s->write_request(GET => "/", 'User-Agent' => "Mozilla/5.0");

my($code, $mess, %h) = $s->read_response_headers;

while (1) { my $buf; my $n = $s->read_entity_body($buf, 1024); last unless $n; print $buf; }

Page 23: Perl

CGI module

• for CGI scripts (ie web programming)#!/usr/bin/perl use CGI;my $cgi = new CGI;

#reading parameters from a from$x = $cgi->param('X'); #where X is the

name$y = $cgi->param('Y);

Page 24: Perl

CGI module (2)

• create web pages• you can a normal print statements or the

functions provided by CGI modulesprint $cgi->header;

—html header needed by the browsers

print "hello World\n";—STDOUT is redirected to the browsers

print $cgi->h1("Hello World");—print "<h1>Hello World</h1>\n";

print $cgi->hr;see the CGI manpages or perldoc for more.

Page 25: Perl

CGI module (3)

• you can run perl cgi scripts from the command line and type in parameters.—This allows you test the scripts without a web

server and browser—Some versions of the CGI module it will stop

and wait for parameters– for parameters: name=value– then control-D (UNIX)/control-z (windows)

—Newer versions will process parameters as part of the command line arguments.

– To change to wait for parameters – use CGI "-debug"; #after you debugged the script,

remove the "-debug"

Page 26: Perl

ftp module

use Net::FTP;$ftp = Net::FTP->new(ftpsite);$ftp->login(username,password);$ftp->binary; #set to binary transfer$ftp->hash(true); #turn on hashing$ftp->get(FILENAME); #get filename (can include

directory as well—file is put in current working directory

@files = $ftp->ls(); #a directory or filename can be include inside the ().

$ftp->quit; #close ftp connection• all of these return true/false values, the next slide

is an ftp site to get updates for RedHat linux

Page 27: Perl

FTP script example (getfile.pl)#!/usr/bin/perl$file = $ARGV[0]; $todir = $ARGV[1];use Net::FTP;@toget = ();$ftpsite = "updates.redhat.com";while(1) { if ($ftp = Net::FTP->new($ftpsite)) { if ($ftp->login("anonymous","seker\@k2.cs.uwyo.edu") ) { $ftp->binary; $ftp->hash(true); $f = $todir.$file; if ($ftp->get($f)) { print "yes\n"; last; } else { print "no!, Trying again.\n"; } } else { print "anonymous connection denied.\n"; $ftp->quit; redo; } } else { print "Not able to connect to $ftpsite\n"; sleep(10); }}

Page 28: Perl

another FTP script example (getallfiles.pl)#!/usr/bin/perluse Net::FTP;$ftpsite = "updates.redhat.com";@dir = ("/8.0/en/os/i386/",

"/8.0/en/os/noarch/", "/8.0/en/os/i686/");foreach $todir (@dir) {while(1) { if ($ftp = Net::FTP->new($ftpsite)) { if ($ftp->login("anonymous","seker\

@k2.cs.uwyo.edu") ) { $ftp->binary; $ftp->hash(true); print "In, changeing directories\n"; $ftp->cwd($todir); print "In, getting list\n"; @toget = $ftp->ls(); print "Done.\n"; $ftp->quit; last; } else { print "anonymous connection

denied.\n"; $ftp->quit; redo; } } else { print "Not able to connect to

$ftpsite\n"; sleep(10); }}

print "Getting new rpms\n";$i = $#toget;foreach $file (@toget) { if ( -e "$file") { --$i; next; } print "getting $file in $todir\n"; $x = system("getfile.pl $file $todir"); --$i;}}#end of foreach loopprint "Finished \n";

• This scripts functions to lists all the files in the @dir array, found out they have already been downloaded. If they haven't, then call getfile.pl script to get each file.

• The reason for the second script timeout of a ftp session will cause the script to terminate.

• All files are downloaded to the current working directory.

Page 29: Perl

STMP module

use Net::SMTP; #for sending e-mail.use Sys::Hostname; #for hostname command (next

line)$smtp = Net::SMTP->new(hostname);$smtp->mail("seker\@uwyo.edu"); #from$smtp->recipient("username\@somewhere");#

mail to$smtp->data(); #start of mail data$smtp->datasend("Subject: Whatever");

—for the subject line

$smtp->datasend("\n\n"); # end of mail headers $smtp->datasend("bah.. bah… bah…\n");

—what ever you want to say, use as many times as needed.

$smtp->dataend(); #end of mail message$smtp->quit(); #sends the e-mail.

Page 30: Perl

SMTP example#!/usr/local/bin/perluse Net::SMTP; use Sys::Hostname;open FP, "grading2150.csv";

#header line creation.#header line is created here, but

left out for space reasons.#read each students grade, then e-

mail with header linewhile (<FP>) { chop;chop; #get rid of eol

marker, and windws eol marker @list = split ',';# create name and e-mail, plus some

clean up $f =lc $list[0]; $l = lc $list[1]; $name = "\u$f,\u$l"; $name =~ s/\"//g; $emails = $list[$#list]; $emails =~ tr/A-Z/a-z/; $emails =~ s/\"//g;

if ($emails ne "") {# put together grade variable here, again

left out $hostname = hostname; $smtp = Net::SMTP->new($hostname); $smtp->mail("seker\@uwyo.edu"); #from

line $smtp->recipient($emails); #to line

$smtp->data(); #start data $smtp->datasend("Subject: Course

grades\n"); #subject line $smtp->datasend(""); #line to

separate header lines from body of the test.

$smtp->datasend("\n\nName: $name\n"); $smtp->datasend("$head\n"); $smtp->datasend("$grade\n"); $smtp->datasend("\n"); $smtp->dataend(); $smtp->quit(); } else {

print "no e-mail for $name \n"; }}

Page 31: Perl

Perl, ODBC, and MYSQL

• The ODBC modules can be added to perl from http://www.cpan.org for just about any database you want to connect to.

• The MYSQL modules were added as of redhat 9 distribution and mysql, so I going to use them for this.

Page 32: Perl

Connection to MYSQL

• First we need the module called DBIuse DBI; #command to load it into perl• Now we need to connection to our

databasemy $dbh = DBI-

>connect( "dbi:mysql:database=YOURDATABASE", 'USERNAME','PASSWORD');

• $dbh is an object used to talk to the database after a successful connection.

Page 33: Perl

Connection Examplemy $dbh = DBI->connect("

dbi:mysql:database=webacc", 'test','csteach');

unless($dbh) { #make sure a connection was made,

otherwise #exit warn "Unable to connect to mysql

($DBI::errstr)\n"; exit 0;}• $DBI::errstr will tell you the error

received.

Page 34: Perl

accessing the database

• Once connected, we can create SQL statements to list, update, insert, delete data in the database.

• There are two different functions depending on whether there is data coming back (say a SELECT) or not.

Page 35: Perl

Using a SQL Select statement• We also need a second variable to hold the data.

—I have a habit of using $sth, but the name is not relevant.

• First the sql statement needs to be created$sql = 'SELECT * FROM test ';• Now we need to prepare and execute the

statement$sth=$dbh->prepare($sql);$sth->execute;• After that we are ready to read in the data• Uses $sth->fetchrow, which brings back one row

at a time, using an array from the fields@arr = $sth->fetchrow;

Page 36: Perl

Using a SQL Select statement (2)• Generally speaking fetchrow is done with

a loop, so you don't have know how many rows are returned.

while (@arr = $sth->fetchrow) { #then deal with each row. fields in @arr}• Lastly we need to tell the database we are

done with this query.$sth->finish;

Page 37: Perl

Other commands

• SQL commands where there is no data coming back, say an insert, update, or delete, the commands are simpler.

$sql = "delete from test where name='k2' ";• Execute the statement$dbh->do($sql);• If there was an error, we can use

$DBI::errstrprint "problem: ($DBI::errstr)\n";

Page 38: Perl

References

• There is a lot more to the DBI, which you can look up if you are interested

• reference: (official guide)

Programming the Perl DBI, Descartes and Bunce, O'Reilly, 2000

Page 39: Perl

Other modules

• XML modules• database ODBC modules• TK modules (included in ActivePerl)

—for scripts with GUI interfaces

• numerous ones for File I/O and reading/writing file types, such as image files, even MS office documents.

• everything from audio and video modules to a networking, such telnet to a cisco router and ssh.

• See www.cpan.org for the module list.

Page 40: Perl

Windows Win32 module• The win32 module and it extensions allow access

to the windows O/S system• The following lists just some of the functionality

of the win32 module and extensions—Win32::GetOSName()

– returns undef, Win32s, Win95, Win98, WinMe, Win2000, WinXP/.Net, WinNT3.51, or WinNT4

—Win32::MsgBox(MESSAGE [, FLAGS [, TITLE]])– Create a dialogbox containing MESSAGE, see doc for more

info.—Win32::InitiateSystemShutdown(MACHINE, MESSAGE,

TIMEOUT, FORCECLOSE, REBOOT)– initiate a system shutdown or reboot.

—Win32::LoginName– return username of owner of the current perl process

—Win32::NodeName– Returns node name of current windows machine

—use Win32::Process– access process creation and management, including

functions for kill, suspend, resume and priorities of process

Page 41: Perl

Windows Win32 module (2)—use win32::AuthenticateUser

– user authentications for domains

—use Win32::TieRegistry– Powerful and easy ways to manipulate a registry

—use Win32::Netadmin– manage network groups and users

—use Win32::NetResourcemanage network resources

—use Win32::EventLog – process the eventlog

—use Win32::Internet– use windows to access http, ftp, and gopher connections

—use Win32::Service– manage system services

—use Win32::Sound– An extension to play with Windows sounds

Page 42: Perl

QA&