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

Hi,

This problem applies to any manner of TCP/IP data exchange, and in this case I'm using POE.

So, using POE::Component::Client::TCP, I'm trying to get some 32 bytes of data from a process. It goes like this. I send a command code, the other guy gets it, and then replies with 32 bytes of data. That's all on the localhost interface. So far so good. Ethereal shows what's going on and the 32 bytes of data are indeed replied. But then, the other guy, after sending his 32-byte reply, *immediately* disconnects, resulting in my POE::Component::Client::TCP exiting with:

Client 2 got read error 0 (Normal disconnection)

The ServerInput event never gets the data. So I tried getting the data using ServerError and ServerFlushed but it these also do not get the 32 bytes of data before the component exits. If only I could get the data then I could send it to another session to get it process.

Maybe I just got the whole thing not right... Maybe I should use a server component to try to get the data from this other process ?

How would you handle such a TCP/IP process that, once you query it for data, sends it and immediately disconnects.

Any suggestions appreciated !

Replies are listed 'Best First'.
Re: Unexpected TCP/IP disconnect
by PodMaster (Abbot) on Feb 21, 2006 at 10:26 UTC
    Try delaying the disconnect until you've confirmed the data has been sent and received. Try turning debug on :)
    update: and turn trace on
    Maybe I just got the whole thing not right... Maybe I should use a server component to try to get the data from this other process ?
    No, POE::Component::Client::TCP should work.

    Maybe you can show some code that demonstrates the problem.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Unexpected TCP/IP disconnect
by BrowserUk (Patriarch) on Feb 21, 2006 at 12:22 UTC
    How would you handle such a TCP/IP process that, once you query it for data, sends it and immediately disconnects.

    With threads :)

    Using this multithreaded server as a stand in for your 'send 32 bytes and shutdown the connection' server:

    #! perl -slw use strict; use threads; use IO::Socket::INET; my $s = IO::Socket::INET->new( LocalPort => 9999, Listen => 255, reuse +=>1 ); while( my $c = $s->accept ){ threads->create( sub { printf "Server$$: Got %s", scalar <$c>; print $c chr( 65 + rand(26) ) x 32; $c->shutdown(2); } )->join; }

    And this client that starts 5 threads that each make five requests to the server, whilst the main thread retrieves the output and 'processes it':

    #! perl -slw use strict; use threads; use Thread::Queue; sub getIt { require IO::Socket::INET; my $tid = threads->self->tid; my( $Q ) = @_; my $data; for( 1 .. 5 ) { my $c = IO::Socket::INET->new( 'localhost:9999' ); ## Connect print $c 'Give me 32 bytes please'; ## Ask chomp( $data = <$c> ); ## get $c->close; ## close $Q->enqueue( "$tid:$data" ); ## Queue sleep int rand( 5 ); } $Q->enqueue( undef ); ## Signal thread done } my $Q = new Thread::Queue; my @threads = map{ threads->create( \&getIt, $Q ) } 1 .. 5; for( 1 .. 5 ) { ## Handle 5 threads dying while( my $in = $Q->dequeue() ) { ## Get data my( $tid, $data ) = split ':', $in; ## Separate who from what print "Client: Got '$data' from thread:$tid"; } } $_->join for @threads; ## Wait for threads to die

    A test run looks like this

    [12:20:32.79] C:\test>start /b tserver [12:20:35.60] C:\test>tclient Server: Got Give me 32 bytes please Client: Got 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ' from thread:4 Server: Got Give me 32 bytes please Client: Got 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV' from thread:1 Server: Got Give me 32 bytes please Client: Got 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' from thread:3 Server: Got Give me 32 bytes please Server: Got Give me 32 bytes please Client: Got 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' from thread:2 Client: Got 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY' from thread:5 Server: Got Give me 32 bytes please Client: Got 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' from thread:4 Server: Got Give me 32 bytes please Client: Got 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' from thread:4 Server: Got Give me 32 bytes please Client: Got 'LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL' from thread:4 Server: Got Give me 32 bytes please Client: Got 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' from thread:5 Server: Got Give me 32 bytes please Client: Got 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' from thread:2 Server: Got Give me 32 bytes please Client: Got 'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP' from thread:4 Server: Got Give me 32 bytes please Client: Got 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' from thread:1 Server: Got Give me 32 bytes please Client: Got 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ' from thread:3 Server: Got Give me 32 bytes please Client: Got 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' from thread:1 Server: Got Give me 32 bytes please Client: Got 'HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH' from thread:5 Server: Got Give me 32 bytes please Client: Got 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' from thread:2 Server: Got Give me 32 bytes please Client: Got 'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD' from thread:1 Server: Got Give me 32 bytes please Client: Got 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' from thread:3 Server: Got Give me 32 bytes please Client: Got 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' from thread:2 Server: Got Give me 32 bytes please Client: Got 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW' from thread:5 Server: Got Give me 32 bytes please Client: Got 'NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN' from thread:3 Server: Got Give me 32 bytes please Client: Got 'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII' from thread:1 Server: Got Give me 32 bytes please Client: Got 'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU' from thread:3 Server: Got Give me 32 bytes please Client: Got 'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT' from thread:2 Server: Got Give me 32 bytes please Client: Got 'RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR' from thread:5

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.