Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

How can I determine the server is waiting for input in POE::Wheel::ReadWrite?

by woosley (Beadle)
on Nov 15, 2009 at 07:40 UTC ( [id://807234]=perlquestion: print w/replies, xml ) Need Help??

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

Hi all, I worte a POE job server, just like what do. when I use POE::Component::Client::TCP to write a interactive client, I found I can not determine when is the end of a command.
ServerInput callback of POE::Wheel::ReadWrite can be used to get all the output of the command, it is line-based, but I want to input anther command when the server output is over, I definitely can not yeild a callback whenever a single line from server comes to the server. So how can I determine the end of the command output from the server?
here is my simple client code.
  • Comment on How can I determine the server is waiting for input in POE::Wheel::ReadWrite?

Replies are listed 'Best First'.
Re: How can I determine the server is waiting for input in POE::Wheel::ReadWrite?
by rcaputo (Chaplain) on Nov 15, 2009 at 07:55 UTC

    If your client/server protocol is line-based, then presumably your server would send some kind of "end of job" marker. Your client can detect this marker and begin the next job.

    For example, SMTP uses a single period on a line by itself to signal the end of a message body. Be careful to prevent jobs from including that text in their output. SMTP escapes body lines that are single periods so that they aren't confused with end-of-message markers.

      Thanks for the reply, this is a solution.
      But I do prefer POE can auto-detect that the server side has send out it's output. I can "telnet" to the server and run these commands, when the command sent out the result, I can input another command. Is any possible way to do it without adding any end mark?


        When you send messages across a network, they get chopped up into pieces. The problem is: you cannot know ahead of time how many pieces the message will get chopped up into. Therefore, the only way to know when to stop trying to read the bits and pieces of the messages coming across the network is if there is some kind of "end of message" marker.

        Some other "end of message" markers are: If the other side of the connection is always guaranteed to send messages of the same length, you can stop reading after receiving x number of bytes. Or, if the other side always uses the first two bytes of the message to indicate how many bytes the message length is, you can read the first two bytes, then read the next x number of bytes after that and then stop reading. Or, if the other side always closes the connection after sending a message, you can use that event as an end of message marker.

        But the bottom line is you can't automatically detect when to stop reading because you can't know ahead of time how many pieces your message got chopped up into when it was sent across the network.

        I hope that helps shed some light on the situation.

        I can "telnet" to the server and run these commands, when the command sent out the result, I can input another command.

        How do you know the command finished sending out the result? By the prompt you are given once it's done. Or maybe because you recognize the format of the output. Or maybe you assumed it was done based on the passing of time. Those are examples of the aforementioned "end of job marker".

        A computer cannot detect the appropriate condition without being told what it is. There's too much variety in the possibilities. They usually come in two varieties:

        • A prefix that indicates how much data is coming.

          For example,

          • Perl strings are stored as a structure that include length field.
          • The header of IP packets indicate how big the packet is.
          • HTTP response can indicate the size of the response in the Content-Length header.
        • A sentinel value indicates the end has been received.

          For example,

          • C strings end at the first occurrence of byte '\0'.
          • bash indicates it's ready for another command by echoing $.
          • HTTP response without a Content-Length header are ended by socket closure.

        If you're doing it by hand how do you determine that the command has finished its output?

Re: How can I determine the server is waiting for input in POE::Wheel::ReadWrite?
by Joost (Canon) on Nov 15, 2009 at 21:27 UTC
    As a simplification, you may want to think of the processing of network data the same way as reading a file while some other process is writing to it.

    You cannot determine without some protocol when a "block" of data is complete. The common solutions to this problem are:

    a) the above mentioned "end of block" marker. In the case of a line-based protocol, the newline character serves as an end-of-block marker. This is especially useful if its inefficient to know the length of a block in advance (usually, because the block is large and takes a long time to compute). And line-based protocols are just nice to read for humans, which can also be a big help in analyzing any problems.

    b) prefix the block with its length. HTTP for instance provides a mechanism for this using the content-length header. Many binary protocols work the same way. When possible, this gives a few advantages over end-of-block markers; the client will know how much memory to allocate for the incoming data, and it can make it easier to pass the data on without any additional processing.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://807234]
Approved by Corion
Front-paged by ikegami
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-18 20:51 GMT
Find Nodes?
    Voting Booth?

    No recent polls found