Draff has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,
I hope to get some advice, currently i have already done the whole system to connect to the a messaging server using telnet. One of my function here is using the socket connect to telnet to the messaging server to get the whitepages detail of the user. Below is the function where i use to capture the result after i have issue the command.

sub SOCKETread{ my $s = $_[0]; my $buffer = ""; my ($ready, $fdmask, $nfound); do{ $numBytes = sysread($s, $buf, 256); $buffer .= $buf; # loop til we have a complete response if (($buf =~ /^OK/im) || ($buf =~ /^Error/im) || ($buf =~ /<*> +/)){ $numBytes=0; } } while ($numBytes); return $buffer; }

Actually this function i found out that, it has a small bug, which coz my client system sometime stop in the middle of no where, and the webpage also time out. Coz it take until the telnet session close only exit this function for the next task.
First the bug is in the IF statement above. This is because, the whitepage content huge data, and the $buf each time only capture 256 bytes, unstablely maybe less. The problem occur when the $buf get from the sysread is ended with "...O" not "...OK". And it loop again coz the telnet still return something, the next loop which capture in the $buf only the "K", so it would not jump out from the do..while statement becoz it doesn't meet the condition. Finally it stuck at the sysread because it still think that there might be something to come out but maybe slow, but the data is already finish display.
What should i do to overcome this problem, actually it is easy to change the condition, in deep of $buf to $buffer. But if this is a huge data, consider about 500 user, after joining each time make a check to it will it slow down the performance. What is the best way that i can do.
Thank you

Update: added <code> tags. larsen

Replies are listed 'Best First'.
Re: Need Help On the Socket Connection.
by tadman (Prior) on May 15, 2002 at 17:23 UTC
    Maybe using IO::Socket will make your life easier, since it doesn't require getting down and dirty like you have done with sysread. It's an IO::Handle, which makes reading and writing from it a lot simpler, and besides, making sockets has never been easier.

    As an additional note, you probably want to use strict. You have declared $buffer and then you use $buf, and $numBytes is undeclared, at least in your example.

    Further, your last regular expression (regex) is specified as /<*>/. You may not realize that "*" is special, meaning here "zero or more of the previous character", so this will match any of the following: >,<>,<<>,<<<>, etc. It will not, however, match <*> since this is not just angle brackets. For that, you need to use /<\*>/.

    If you meant to specify that there is something inside angle brackets, then what you need is /<[^>]*>/ or /<([^>]*)>/ where the second version puts the contents of the brackets in $1.
Re: Need Help On the Socket Connection.
by Caillte (Friar) on May 15, 2002 at 16:54 UTC

    If, as I assume, your error conditions will be on a line of their own, try this:

    sub SOCKETread{ my $s = $_[0]; my $buffer = ""; my ($ready, $fdmask, $nfound); $buffer = read_line($s); # do stuff with buffer return $buffer; } sub read_line { my $s = shift; my $maxline = 50; my $buffer = ''; my ($buf, $bytesread); do { $bytesread = sysread($s, $buf, $maxline); $buffer .= $buf; } while($bytesread == $maxline and $buffer !~ /\n$/); return $buffer; }

    I didn't have time to test this, sorry, but it should work as shown

    Update:Put correct test in the while statement.

    This page is intentionally left justified.

Re: Need Help On the Socket Connection.
by Rex(Wrecks) (Curate) on May 15, 2002 at 17:31 UTC
    I'm not sure about how this may affect the rest of your code, but using Net::Telnet will make your life ever so much easier if all you are doing is connecting to telnet.

    I wrote a review that may be of interest to you, it is over here.

    "Nothing is sure but death and taxes" I say combine the two and its death to all taxes!