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

Hi, I'm just starting to use POE. Here's a basic question I'm stuck with: I've got a simple TCP server using POE(with my own filters), which accepts some commands and responds with 1 or 0 depending on whether the commands are valid. When I test it using telnet, all is fine. What I'm trying to do is to write a simple client in POE, I'd like to make a connection, and then just send the server a sequence of commands. I'd like to be able to handle the server response for each command. But I can't seem to control how the sequence is sent: in some runs, each is sent one at a time; in some other runs, all is sent in one batch. Is there a way to make sure each command is sent individually? sort of flushing IO after each command?
#!/usr/bin/perl -w # # simple client # use warnings; use strict; use POE; use POE::Component::Client::TCP; use POE::Filter::Stream; my $host = "localhost"; my $port = 38888; POE::Component::Client::TCP->new( RemoteAddress => $host, RemotePort => $port, Filter => "POE::Filter::Stream", Connected => sub { print "connected to $host:$port ...\n"; #now send 10 commands in a row. # is this the right way to send a sequence? foreach my $i(1..10){ $_[HEAP]->{server}->put("command-$i"); } }, ConnectError => sub { print "could not connect to $host:$port ...\n"; }, ServerInput => sub { my ( $kernel, $heap, $input ) = @_[ KERNEL,HEAP, ARG0 ]; print "$input\n"; }, ); POE::Kernel->run(); exit 0;
UPdated: it still doesn't seem to work if I add "\n" to the end of commands, and use the Line filter.

Replies are listed 'Best First'.
Re: POE: how to flush io?
by thekestrel (Friar) on Mar 29, 2005 at 23:42 UTC
    Johnnywang,
    There is a good post here from the author of POE rcaputo that might give you a few ideas.

    Regards Paul
Re: POE: how to flush io?
by polettix (Vicar) on Mar 30, 2005 at 10:28 UTC
    I'm not a POE expert (I actually discovered it today, thank you :), but I would guess that it's not a POE-related problem.

    TCP implementations usually adopt some techniques to send data "packed" together if they can; I'm thinking about optimisation algorithms like Nagle (if I remember well). You don't notice this in telnet, because you probably write your commands and wait for a response - and the initial wait should be sufficient for TCP to decide that it's time to send something. On the other side, your program pumps all the commands together, so if the resources in your machine are enough it will send them all together, while it will probably do something more grateful to you if load is a bit higher.

    My quick-and-dirty fix would be putting some delay between requests, or even syncronize them with responses. But the best solution would probably be to make the server more robust and have it accept batches of commands, while doing some caching of a possible truncated command, whose completion could be on its way through the net. Given the fact that I don't know how your server looks like, I cannot say much more!

    Flavio

    Don't fool yourself.
Re: POE: how to flush io?
by johnnywang (Priest) on Mar 31, 2005 at 21:13 UTC
    As it turns out, after looking through much of POE code, that I was doing it all wrong. On the server, I was using my own filter, which wasn't doing the right thing, basically I didn't know that a filter is supposed to work on the raw stream. After I removed my own filter, and let both the server and the client use their default (POE::Filter::Line), all worked out fine.