Results 1 to 6 of 6
  1. #1
    Join Date
    Apr 2010

    Question PERL : how to flush input buffer?


    Better than tons of words...
    perl -e 'use IO::Socket; my $s = new IO::Socket::INET (Listen=>10, LocalHost=>"", LocalPort=>2000, Proto=>"tcp", Reuse=>1); $s->autoflush(1); if( my $c = $s->accept() ){  if( sysread($c, my $byte, 1) ){ print("A: \"$byte\"\n"); }   $c->flush();  if( sysread($c, my $byte, 1) ){ print("B: \"$byte\"\n"); } } close($s);'
    Then :
    # telnet 2000
    Connected to
    Escape character is '^]'.
    Connection closed by foreign host.
    The perl returns :
    A: "a"
    B: "b"
    What I am trying to do is to flush the input buffer of $c. If it was working, I would never see "b".
    (of course, flush is for output, it would make more sense to call it "clear" for the input)
    Is there any way to do this without reading?


  2. #2
    Join Date
    Oct 2005
    The output of the program is correct. And you assumed incorrectly.
    You need to understand how to correctly do I/O in perl.

    1. flushing only works IF you are using buffered I/O functions, that is, you are using the built-ins like print(), <> operator, read() functions, etc.
    2. you are using sysread(), which is for unbuffered I/O. Since there is no buffer, there is nothing to "clear".
    3. sysread() is a blocking command, which will block for input (i.e. wait until there is data or error, then return).
    4. Avoid mixing buffered I/O functions with unbuffered I/O functions.

    For more info, consult `perldoc -f sysread` vs. `perldoc -f read`.

    In your case, if you simply want to read one character at a time, you can:

    a. read data into a buffer (array / string), then split and get the slice/substring you want. - this will still read the entire pending data from the socket anyway but then you control which to output / process.

    b. better yet, rewrite your algorithm to use select() to check if the input filehandle has pending data or not, and then react accordingly. This is a lot more complicated but you have the option to throw away pending input if it's not needed.

    c. if you want to improve using select() based solution, you may opt to write your program using async / event-driven libraries like AnyEvent.
    Last edited by cygnusd; 11-14-2013 at 12:14 PM. Reason: fixed typos / formatting

  3. #3
    Join Date
    Apr 2010
    Thank you cygnusd for the answer.

    I am sorry but there's something that doesn't make sense to me...
    In one hand you talk about unbuffered data, and in the other hand you say "to check if the input filehandle has pending data or not".

    But isn't "pending data" a buffer?
    Whenever I say buffer, I mean "pending data", I don't see what else the word "buffer" could mean.

    So when I read 1 byte with sysread, if there are 4 bytes already sent by the client and received by the server, there are 3 more bytes somewhere, whatever we name it. I call that a buffer and my goal is to clear it without wasting cpu reading it.

    Also, I forgot to mention that in my final project I use non-blocking mode with blocking(0) whenever I read.


  4. #4
    Join Date
    Oct 2005
    If you read how I structured my recommendations, I mentioned three (3) alternatives namely a,b and c.
    Also, please read the first 4 analysis I enumerated.

    The main point of my [b] recommendation is to use select() and be non-blocking. Yes, pending data implies buffering, and that's at the OS level and abstracted out for you. You can't flush IN for input filehandles. Data read by the OS will already be in its buffers. That's why select() will help you determine if there is pending data in the OS buffers. It's up to you to discard data not needed.

    Wasting cpu cycles, in my book, is premature optimization. OS-level buffering is supposed to improve efficiency and performance for you (if you really dig into the main reason of buffering).

    Are you sure you are doing non-blocking I/O properly? I enumerated that sysread() is blocking, even if the socket was marked nonblocking. Again, select() is your tool for this.

  5. #5
    Join Date
    Apr 2010



    All right, so I guess the answer to the original question is:
    "No, data in the buffer can't be flushed without reading it."
    (meaning getting all bytes even if you don't care for the content)

    BTW I've been programming in perl intensively for the last 13 years.

  6. #6
    Join Date
    Oct 2005
    mrbark, I meant no offense with my posts. I really do want to help you; and I believe my response was reasonable in content and reasonable in tone.

    To summarize then, what I understood to be what you want is to "clear" the input filehandle. You can read the data and ignore it yourself (to get it "cleared" or "flushed"). You can also do a seek() to the end of the input filehandle, where the OS will read the data anyway but will "ignore" or skip the data along the way.

    P.S. I respect you and what you know and I'm not treating you any lower, but please, I think the huge bold heading "shoutout" and the 13-years-in-perl factoid are unnecessary.

Similar Threads

  1. perl: write user input to text file
    By Ninjadeller in forum Programming Discussion
    Replies: 11
    Last Post: 09-09-2012, 09:04 AM
  2. iconv: unable to allocate buffer for input: Cannot allocate memory
    By Ba$im in forum Hosting Security and Technology
    Replies: 12
    Last Post: 07-01-2009, 02:56 AM
  3. failed to flush buffer
    By phntje in forum Hosting Security and Technology
    Replies: 5
    Last Post: 05-28-2008, 02:39 PM
  4. Output buffer - flush
    By anjanesh in forum Hosting Security and Technology
    Replies: 0
    Last Post: 05-28-2006, 10:12 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts