http://qs321.pair.com?node_id=1035631

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

Hi, I have made a socket that connects to a remote server and listens for incoming data, it writes the data to a file. The data stream is continuous, any breaks in the stream are not based an any pattern. The code works mostly, except that a new file is never created. I would like a new file to be created every 15 minutes. I realize this is because an EOF is never reached from the socket, and the socket is blocking the code from moving forward. I am not sure making the socket non-blocking will get me what I want, as there will almost always be data in the buffer to be read. Is there a way to get the desired behavior? I was considering either trying to use Fork in some way, or making a seperate script to handle to file seperation with the current script writing to generic file. Thanks, Eric

while($continue){ if ($socket->connected){ $quarter = $minute - ($minute % 15); ## if quarter != quarter 15 minutes has passed, create + new filename with the next 0 15 30 45 designation if($cur_quarter != $quarter){ ## close current file and move it to directory + for further processing close $fout; move("$dir.$filename","/home/ed/falbee/chrysle +r_asn/lu62asns"); $cur_quarter = $quarter; ## pad cur_quarter with 0 (make sure has two d +igits) $cur_quarter .= '0' x (2 - length($cur_quarter +)); $filename ="$date$cur_quarter"; open ($fout, ">>", $filename); } local $/ = '^\'; my $line = <$socket>; print $fout $line; }

Replies are listed 'Best First'.
Re: IO::Socket blocking question
by BrowserUk (Patriarch) on May 28, 2013 at 18:25 UTC
    local $/ = '^\';

    I suspect that ^\ is meant to be control-backslash -- ie. ascii 28, otherwise known as FS for "file separator".

    If so you are not setting the INPUT_RECORD_SEPARATOR $/ to chr(28), but rather to the two character string consisting of a caret (^) and a backslash (\).

    To set $/ to FS, you can use any of the following constructs:

    • $/ = chr(28);
    • $/ = chr( 0x1c );
    • $/ = "\c\\";
    • $/ = $;;
    • $/ = "\x1c";

    (I'd advise one of the first two for clarity.)

    If my suspicions are correct, then once you've set the input record separator correctly, you may find that the rest of your code functions as expected.

    It is possible to enter ascii 28 by typing ', control+backslash, ' (at least on windows and my keyboard), but it is at best an obscure and easily misunderstood way of doing so.)


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks for both of your replies, changing the local $/ line corrected the issue. I initialize and updated the $minute variable outside of that code block, there was more going on, and I thought this was the portion most relevant to the socket. Thanks again for both responses!
Re: IO::Socket blocking question
by jethro (Monsignor) on May 28, 2013 at 15:58 UTC

    Where do you set/update $minute ?