Thanks for the good tip John and Bill,

Will give sysread a go.

$Bill Luebkert wrote:

Foo Ji-Haw wrote:

Hi all,

Just want to share and ask something about reading from the sockets.
Normally my connection to the Other Side receives line inputs. But not all the time the eol character is standard across the various remote connections; sometimes it's just a 0x0D.

I realise that <$socket> does not always work, even with $/=char(13). The safest way so far seems to be 'doing it yourself' with a loop repeating getchar() calls until you hit the expected EOL character. It works, but I suspect the high hit rate on the function call is not optimal.

If anyone has a better idea (or my $/=char(13) is just plain wrong), please reply. Thanks.

I prefer to do all my socket stuff like this:

1) Do a can-read or can_write after an IO::Select has set up your
  sockets to decide if it makes sense to read/write.

2) If you get the go ahead from that, do a sysread for x bytes and
  return the number of bytes to the caller (or EOF/ERR condition
  if present) along with the data actually returned.
  For the write, it would be a syswrite for the size requested and
  return the number actually sent (or EOF/ERR condition) - the caller
  will have to keep track whether it all got sent or not and try
  the rest later after another can_write says to.

All your calls should use the same read and write routines as described
above.  You could also check for exceptions when you check the can_xxx
conditions.  If you're asymchronously reading and writing, you probably
want to check for pending writes to do before trying to read more data
to process.  It helps to create an output Q for each socket and not
read on that socket until all the output is out or you'll end up with
a lot of pending output data.

Here are sample routines that I've used :

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub read_sock { # my $bytes = read_sock ($S, \$buffer, [$bufoff, [$buflen]])
        my $S = shift;
        my $bufref = shift;
        my $off = shift || 0;
        my $len = shift || $::MAX_READ;
        my $buffer = $bufref;
        if (not ref $bufref) {
                DLOG "Usage: read_sock (socket, bufref[, len])\n";
                $buffer = \$bufref;
        }
        if (not defined $$buffer) {
                $$buffer = '';  # create a bufref if none exists yet
                DLOG "Had to define \$\$bufref\n";
        }

DLOG "enter read_sock $S, $buffer, $len\n";

my $bytes = sysread $S, $$buffer, $len, $off;
if (not defined $bytes or $bytes < 0) {      # read error
        DLOG "read_sock return ERR: $!\n";
        return -1;
} elsif ($bytes == 0) {                 # eof
        DLOG "read_sock return EOF: $!\n";
        return 0;
}
DLOG "read_sock return $bytes\n";
return $bytes;

}

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub write_sock { # my $bytes = write_sock ($S, \$buffer, [$bufoff, [$buflen]])
        my $S = shift;
        my $bufref = shift;
        my $off = shift || 0;
        my $buffer = $bufref;
        if (not ref $bufref) {
                DLOG "Usage: write_sock (socket, bufref[, off[, len]])\n";
                $buffer = \$bufref;
        }
        my $len = shift || length $$buffer;

DLOG "enter write_sock $S, $buffer, $off, $len\n";

my $bytes = syswrite $S, $$buffer, $len, $off;
if (not defined $bytes or $bytes < 0) {      # write error
        DLOG "write_sock return ERR: $!\n";
        return -1;
} elsif ($bytes == 0) {                 # eof
        DLOG "write_sock return EOF: $!\n";
        return 0;
}
DLOG "write_sock return $bytes\n";
return $bytes;

}

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub DLOG (@) {          # this is my debug logging routine $db is open to log 
file

return if not $debug;

foreach (@_) { print $db $_; }

}

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -




_______________________________________________
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to