Re: Lost data on socket - Can we start over politely?

From: Vorxion (vorxion_at_knockingshopofthemind.com)
Date: 03/30/04


Date: 30 Mar 2004 16:56:06 -0500

In article <4069a132.0@juno.wiesbaden.netsurf.de>, Thomas Kratz wrote:
>[ code snipped ]
>
>Sorry, but the code is still too cluttered to debug it. I have tried,
>really, for about 45 minutes, then I gave up.

Thanks for the effort though. However, this example you gave (I just woke
up in the middle of the "night" and decided to check mail and news quickly,
so I haven't tested it yet) is very helpful. One thing I don't understand
about it though...

>++++ server ++++
>
>use strict;
>use warnings;
>
>use IO::File;
>use IO::Select;
>use IO::Socket;
>
>my $max_buf = 10240;
>
>my $sel = IO::Select->new();
>
>my $srv = IO::Socket::INET->new(
> Proto => 'tcp',
> LocalPort => 4016,
> Listen => SOMAXCONN,
> ReuseAddr => 1,
>);
>
>$sel->add($srv);
>
>die "couldn't create socket" unless $srv;
>
>my $log = IO::File->new('server.log', '>') or die $!;
>$log->autoflush(1);
>
>while ( 1 ) {
>
> foreach my $sock ( $sel->can_read(0.05) ) {
>
> if ( $sock == $srv ) {
>
> my $new = $srv->accept();
> $new->autoflush(1);
> print $log "new connection from ", $new->peerhost,
> ':', $new->peerport, "\n";
> $sel->add($new);
>
> next;
> }
>
> my $buf = '';
> my $clsel = IO::Select->new($sock);

There... -Every- time you go through the loop, you're reconstructing
$clsel as a single-element-holding object containing the current
iteration's object? Could I inquire as to why you're doing this instead of
simply performing the following check on $sel instead of $clsel? Is it
simply a speed optimisation for that block, or is there something inherently
safer in what you're doing that would cause problems if you tried using
$sel?

> while ( $clsel->can_read(0.05) ) {
> last unless $sock->sysread($buf, 1024, length($buf))
> and (length($buf) <= $max_buf);
> }

Wait a second...Doh. *lightbulb* You come in the first time on $sel, but
you're rebuilding $clsel so that you can purely stay -on that socket- until
it's drained? I think I'm startng to see. Could you confirm?

That, and one thing is curious--the docs for foreach() say that adding and
removing elements from something from a list used for the loop is a Bad
Thing[tm]. You're modifying $sel any time there's a connect or disconnect.
Doesn't that throw the foreach() loop out of sync? Not at all a criticism,
it's just that I've had fresh experience with foreach() and changed lists
and elements thereof, and that part of the docs is fresh in my mind. I'm
curious why this causes no difficulties in your example.

This example is definitely worth a shot. If it works properly, I'll have to
adapt it, but it would be tremendously helpful to see a working example,
using select, that doesn't drop data on the floor. I'll let you know how it
turns out. I was just very curious as to why you're rebuilding a
single-element IO::Select handle each iteration, rather than simply having
an 'else' block as an inverse of the server accept(). I -think- I see now,
though.

And I saw your note about not using non-blocking. Gotcha.

Thanks -very much- for the code to test, and will try tonight!

-- 
Vorxion - Member of The Vortexa Elite


Relevant Pages

  • Re: Count Lines in (Huge) Text Files
    ... A few years ago, I was doing some high-throughput disk stuff and my recollection is that I found the same thing you did: larger buffers only helped up to about 8K or so, and past that any improvement was minimal. ... me that with appropriate settings for its buffer, it should perform better, since it ought to be optimized for line-based i/o. ... Assuming what's hurting you in the explicit forloop is the retrieval of the data and not the counter increment, the above should perform basically as well as a plain foreach() loop. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: a question about for and foreach
    ... foreach (@array) { ... why @array are changed after this foreach loop!!! ... The "foreach" loop iterates over a normal list value and sets the ... If any element of LIST is an lvalue, you can modify it by modifying ...
    (perl.beginners)
  • Re: Fastest MacIntel Forth?
    ... loop Sum; ... VALUE imb ... VALUE sum ... VALUE sel ...
    (comp.lang.forth)
  • Re: Re: Last row in foreach loop
    ... foreach loop other then setting up a loop counter that you manually ... foreach (Racecar racecar in RaceCarCollection) ... almost as reasonable to put the processing into a separate method and th= ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: foreach statement output
    ... > I'm still trying to get an understanding of the way a foreach loop loops. ... You can't use the loop variable as an index to your array. ...
    (comp.infosystems.www.authoring.cgi)