Here are some snippets to play with. The first is a general purpose client, which should connect to all the servers.
These all work on my localhost.
#client##############################
#!/usr/bin/perl -w
use strict;
use IO::Socket;
my ( $host, $port, $kidpid, $handle, $line );
( $host, $port ) = ('192.168.0.1',1200);
my $name = shift || '';
if($name eq ''){print "What's your name?\n"}
chomp ($name = <>);
# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port
)
or die "can't connect to port $port on $host: $!";
$handle->autoflush(1); # so output gets there right away
print STDERR "[Connected to $host:$port]\n";
# split the program into two processes, identical twins
die "can't fork: $!" unless defined( $kidpid = fork() );
# the if{} block runs only in the parent process
if ($kidpid) {
# copy the socket to standard output
while ( defined( $line = <$handle> ) ) {
print STDOUT $line;
}
kill( "TERM", $kidpid ); # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
# copy standard input to the socket
while ( defined( $line = <STDIN> ) ) {
print $handle "$name->$line";
}
}
And now some servers. First a very basic one...forking and using IO::Socket
#!/usr/bin/perl
#This is a version that can read and write
#from as many clients as your machine supports.
use strict;
use warnings;
use IO::Socket;
my $server = IO::Socket::INET->new
(
LocalAddr => '192.168.0.1',
LocalPort => 1200,
Type => SOCK_STREAM,
Reuse => 1,
Listen => 5
) or die "could not open port\n";
warn "server ready waiting for connections..... \n";
my $client;
while ($client = $server->accept())
{
my $pid;
while (not defined ($pid = fork()))
{
sleep 5;
}
if ($pid)
{
close $client; # Only meaningful in the client
}
else
{
$client->autoflush(1); # Always a good idea
close $server;
&do_your_stuff();
}
}
sub do_your_stuff
{
warn "client connected to pid $$\n";
while(my $line = <$client>)
{
print "client> ", $line;
print $client "pid $$ > ", $line;
}
exit 0;
}
And now IO::Select with IO::Socket
#!/usr/bin/perl
use IO::Socket;
use IO::Select;
my @sockets;
my $machine_addr = '192.168.0.1';
$main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr,
LocalPort=>1200,
Proto=>'tcp',
Listen=>3,
Reuse=>1,
);
die "Could not connect: $!" unless $main_sock;
print "Starting Server\n";
$readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1)
{
($new_readable) = IO::Select->select($readable_handles, undef, undef
+, 0);
foreach $sock (@$new_readable)
{
if ($sock == $main_sock)
{
$new_sock = $sock->accept();
$readable_handles->add($new_sock);
}
else
{
$buf = <$sock>;
if ($buf)
{
print "$buf\n";
my @sockets = $readable_handles->can_write();
#print $sock "You sent $buf\n";
foreach my $sck(@sockets){print $sck "$buf\n";}
}
else
{
$readable_handles->remove($sock);
close($sock);
}
}
}
}
print "Terminating Server\n";
close $main_sock;
getc();
Here is a super simple one using Socket
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
my $proto = getprotobyname('tcp');
my $port = 1200;
# Create 'sockaddr_in' structure to listen to the given port
# on any locally available IP address
my $servaddr = sockaddr_in($port, INADDR_ANY);
# Create a socket for listening on
socket SERVER, PF_INET, SOCK_STREAM, $proto
or die "Unable to create socket: $!";
# bind the socket to the local port and address
bind SERVER, $servaddr or die "Unable to bind: $!";
# listen to the socket to allow it to receive connection requests
# allow up to 10 requests to queue up at once.
listen SERVER, 10;
# now accept connections
print "Server running on port $port...\n";
while (accept CONNECTION, SERVER) {
select CONNECTION;
$| = 1;
print STDOUT "Client connected at ", scalar(localtime), "\n";
print CONNECTION "You're connected to the server!\n";
while (<CONNECTION>) {
print STDOUT "Client says: $_\n";
print CONNECTION "You said $_\n";
}
close CONNECTION;
print STDOUT "Client disconnected\n";
}
The thing to remember, when trying to decide whether to
use a forking(or threaded) server, versus IO::Select, is how much time each transmission will take. If you are uploading or downloading files, (or something big ), servers based on IO::Select, will block the other clients, while the file transfer occurs. So you probably want a forking server. If the transmissions are short, then IO:Select is probably better. For a really good explanation of basic servers, with heavily commented perl code, go to Golden-UNO and look for the section "Perl". Also check out Net::EasyTCP, which is a nice way to do IO::Select'ed servers, since it incorporates "port passwords", "encryption", and passing "perl hashes" through the sockets.
I'm not really a human, but I play one on earth.
flash japh
|