You may be familar with the following code snippet as it was taken
from some posts in this group. However, whatever I do, I cannot get
this message through the socket immediately which causes the other
side to determine I am in trouble because it hasn't received a health
check. The message finally shows up after I issue the shutdown
command, which is unacceptable. Any ideas? Windows peculiarity?
Dear Your Name Here,
I had a similar problem about a year ago, and it looks like your
problem might be due to that same issue.
A good way to check whether or not your Perl script is working is
to write a receiving script to run alongside your connector script and
see if they are able to talk to each other. I modified your script
slightly and included another script, called "conn.pl" and "rec.pl",
respectively. Here thy are (more follows after the scripts):
#!/usr/bin/perl
# File: conn.pl
use strict;
use warnings;
use IO::Socket;
my $msg = "Take me to your leader";
my $conn = IO::Socket::INET->new( PeerAddr => '127.0.0.1',
PeerPort => '8089',
Proto => 'tcp');
die "Cannot connect: $!\n" unless $conn;
$conn->autoflush(1);
$conn->print($msg);
sleep 100;
print "Program $0 has ended.\n";
__END__
#!/usr/bin/perl
# File: rec.pl
use strict;
use warnings;
use IO::Socket;
my $localPort = 8089;
print "Attempting to connect as server...\n";
my $server = IO::Socket::INET->new(LocalPort => $localPort,
Proto => "tcp",
Reuse => 1,
Listen => 1)
or die "\nCouldn't be a server on port $localPort: $!\n";
my $socket = $server->accept();
print "Got a connection!\n";
while (<$socket>)
{
print "Received: $_\n";
}
__END__
Now create those files in the same directory and open two command
windows (and change the directory of both to the directory you saved
them to). Now start both scripts (start the rec.pl script a few
seconds before the conn.pl script).
You will notice that the rec.pl script says that it "Got a
connection!" yet nothing is ever printed until you hit CTRL-C in the
conn.pl script. This looks like the behavior you were talking about
(in that nothing gets sent until the connection shuts down).
The information DOES get sent, but the problem lies with the
receiving script (rec.pl), not with the connector script (conn.pl).
The reason nothing ever gets printed out (until the conn.pl script is
shut down) is because the "while (<$socket>)" code keeps reading the
socket for characters until it encounters a newline character (or
until the connection is terminated, whichever comes first). It keeps
reading until it hits a newline because a newline is what's stored in
the $/ variable (read about this variable in "perldoc perlvar" to find
out more about it).
Therefore, to fix this problem, you can do one of two things.
Either change the string in conn.pl to end with a newline, like this:
my $msg = "Take me to your leader\n";
or add the line:
$/ = \1;
right before the while loop in the rec.pl script. That line
(according to "perldoc perlvar") makes the "<$socket>" code in the
while condition return every character (instead of every line that's
terminated with a newline).
Note that if you take the second approach, then the while-loop will
loop through every letter, and you'll get output like:
Received: T
Received: a
Received: k
Received: e
Received:
Received: m
Received: e
Received:
Received: t
Received: o