Dear Monks,
I am trying to get started with IO::Multiplex. I have done some Internet searches and found an example in a Perl book and I think I understand it well enough to get started with some sample code (the same sample code most web sites copy and reuse).
My Chat Server code is here
#!/usr/bin/perl -w
# FILE: chatserver_02.pl
# FROM: http://manpages.ubuntu.com/manpages/maverick/man3/IO::Multiple
+x.3pm.html
use IO::Socket;
use IO::Multiplex;
my $mux = new IO::Multiplex;
# Create a listening socket
my $sock = new IO::Socket::INET(Proto => 'tcp',
LocalPort => shift || 2300,
Listen => 4)
or die "socket: $@";
# We use the listen method instead of the add method.
$mux->listen($sock);
$mux->set_callback_object(__PACKAGE__);
$mux->loop;
sub mux_input
{
my $package = shift;
my $mux = shift;
my $fh = shift;
my $input = shift;
# The handles method returns a list of references to handles which
# we have registered, except for listen sockets.
foreach $c ($mux->handles)
{
print $c $$input;
}
$$input = '';
}
My Chat Client Code is here:
#!/usr/bin/perl -w
# FILE: chatclient_02.pl
# FROM: http://manpages.ubuntu.com/manpages/maverick/man3/IO::Multiple
+x.3pm.html
use IO::Socket;
use IO::Multiplex;
# Create a multiplex object
my $mux = new IO::Multiplex;
# Connect to the host/port specified on the command line,
# or localhost:23
my $sock = new IO::Socket::INET(Proto => 'tcp',
PeerAddr => shift || 'local
+host',
PeerPort => shift || 23)
or die "socket: $@";
# add the relevant file handles to the mux
$mux->add($sock);
$mux->add(\*STDIN);
# We want to buffer output to the terminal. This prevents
+the program
# from blocking if the user hits CTRL-S for example.
$mux->add(\*STDOUT);
# We're not object oriented, so just request callbacks to t
+he
# current package
$mux->set_callback_object(__PACKAGE__);
# Enter the main mux loop.
$mux->loop;
# mux_input is called when input is available on one of
# the descriptors.
sub mux_input {
my $package = shift;
my $mux = shift;
my $fh = shift;
my $input = shift;
# Figure out whence the input came, and send it on to t
+he
# other place.
if ($fh == $sock) {
print STDOUT $$input;
} else {
print $sock $$input;
}
# Remove the input from the input buffer.
$$input = '';
}
# This gets called if the other end closes the connection.
sub mux_close {
print STDERR "Connection Closed\n";
exit;
}
When I run the server followed by the client the client gets a "Connection Refused" error message. Here a a few notes I made.
Started server. No packets posted on WireShark. Server window does not post any messages and just sits there as expected (no command prompt).
Start client. Get 2 WireShark packets and one error message in the client window. Server terminal window is still just sitting there with no messages and no new command prompt (as expected). Client window returned to a command prompt.
The client error message is:
socket: IO::Socket::INET: connect: Connection refused at ./chatclient_02.pl line 11.
When I looked at the port numbers I thought it was odd that one was 23 and the other was 2300. Since I am just getting started I don't know if the client and server communicate back and forth on the same port or if one port is used in one direction and another port is used in the other direction.
Looking at the Perl Cookbook (Bighorn Sheep) I found a IO::Multiplex example where the server and client both used address localhost:6901. Thus I modified my code to use 6901 in both programs and I failed in a different way. My notes are here.
After making both ports 6901:
Start server. No packets posted on WireShark. Server window does not post any messages and just sits there as expected (no command prompt).
Start client. Get 3 WireShark packets and 4 error messages in the client terminal window. Server terminal window is still just sitting there with no messages and no new command prompt (as expected).
The four client error messages are:
Use of uninitialized value in unpack at /usr/share/perl5/IO/Multiplex.pm line 352.
Use of uninitialized value in numeric eq (==) at /usr/share/perl5/IO/Multiplex.pm line 352.
Use of uninitialized value in unpack at /usr/share/perl5/IO/Multiplex.pm line 352.
Use of uninitialized value in numeric eq (==) at /usr/share/perl5/IO/Multiplex.pm line 352.
I typed the word "client" several times in the client window, hit return and got 4 packets posted in WireShark.
The first packet was from port 55474 (where did this come from?) to port 6901 and it contained the word "client". The next two were from 6901 to 55474 and the second of these contained the word "client". The last of these four was from 55474 to 6901.
I typed the word "SERVER" several times in the server window. The words appeared in the server window but there were no packets reported by WireShark and the client window did not change.
Thus I am stuck. I don't know if the port number should be the same (as in the book) or different (as in the Internet example). I don't know if the problem is in my code or if one of the attempts had good code but something in my Linux box is blocking the port.
Does anyone have any suggestions?
Thanks,
Bruce