How can I add message delimiters to a UDP stream socat is piping?

Multi tool use
Multi tool use

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite












I am using socat to intercept UDP messages and send them to a named pipe:



socat UDP-LISTEN:9999,fork PIPE:/tmp/mypipe,append



I am able to tail this pipe and see all the messages it receives.



I would like to pipe the output of tail -f /tmp/mypipe to sed to do some post-processing of the messages, but unfortunately some of them are not newline-terminated. This is a problem because it means multiple distinct UDP messages could be on the same line, and also because tail -f /tmp/mypipe | sed ... does not pass the last line if it is unterminated.



Ideally I would like to be able to add a custom message delimiter as they are sent to my pipe, so that I can easily find the message boundaries. If that's not possible then is there some way I can follow this file and pipe the final (potentially unterminated) line to another program for post-processing?







share|improve this question





















  • I was able to get closer to my goal, though it's not perfect. Neither UDP-LISTEN nor UDP-RECV seemed to work -- when I tried to execute a system command to echo a trailing newline it appears they would hang on cat;. Using UDP-RECVFROM like so seems to work: socat -u UDP-RECVFROM:9999,fork SYSTEM:"cat; echo "n""
    – abc
    Jul 27 at 22:21










  • The solution in my comment above appears to suffer from a race condition -- since the receives are forked (as they have to be, else socat exits after the first UDP message) the SYSTEM commands are not executed atomically. I noticed the cat and echo getting interleaved when multiple messages came in at the same time. I serialized it by wrapping it in a lock like this: socat -u UDP-RECVFROM:9999,fork SYSTEM:"(flock -x 200; cat; echo "n";) 200>./udplockfile"
    – abc
    Jul 27 at 22:43
















up vote
5
down vote

favorite












I am using socat to intercept UDP messages and send them to a named pipe:



socat UDP-LISTEN:9999,fork PIPE:/tmp/mypipe,append



I am able to tail this pipe and see all the messages it receives.



I would like to pipe the output of tail -f /tmp/mypipe to sed to do some post-processing of the messages, but unfortunately some of them are not newline-terminated. This is a problem because it means multiple distinct UDP messages could be on the same line, and also because tail -f /tmp/mypipe | sed ... does not pass the last line if it is unterminated.



Ideally I would like to be able to add a custom message delimiter as they are sent to my pipe, so that I can easily find the message boundaries. If that's not possible then is there some way I can follow this file and pipe the final (potentially unterminated) line to another program for post-processing?







share|improve this question





















  • I was able to get closer to my goal, though it's not perfect. Neither UDP-LISTEN nor UDP-RECV seemed to work -- when I tried to execute a system command to echo a trailing newline it appears they would hang on cat;. Using UDP-RECVFROM like so seems to work: socat -u UDP-RECVFROM:9999,fork SYSTEM:"cat; echo "n""
    – abc
    Jul 27 at 22:21










  • The solution in my comment above appears to suffer from a race condition -- since the receives are forked (as they have to be, else socat exits after the first UDP message) the SYSTEM commands are not executed atomically. I noticed the cat and echo getting interleaved when multiple messages came in at the same time. I serialized it by wrapping it in a lock like this: socat -u UDP-RECVFROM:9999,fork SYSTEM:"(flock -x 200; cat; echo "n";) 200>./udplockfile"
    – abc
    Jul 27 at 22:43












up vote
5
down vote

favorite









up vote
5
down vote

favorite











I am using socat to intercept UDP messages and send them to a named pipe:



socat UDP-LISTEN:9999,fork PIPE:/tmp/mypipe,append



I am able to tail this pipe and see all the messages it receives.



I would like to pipe the output of tail -f /tmp/mypipe to sed to do some post-processing of the messages, but unfortunately some of them are not newline-terminated. This is a problem because it means multiple distinct UDP messages could be on the same line, and also because tail -f /tmp/mypipe | sed ... does not pass the last line if it is unterminated.



Ideally I would like to be able to add a custom message delimiter as they are sent to my pipe, so that I can easily find the message boundaries. If that's not possible then is there some way I can follow this file and pipe the final (potentially unterminated) line to another program for post-processing?







share|improve this question













I am using socat to intercept UDP messages and send them to a named pipe:



socat UDP-LISTEN:9999,fork PIPE:/tmp/mypipe,append



I am able to tail this pipe and see all the messages it receives.



I would like to pipe the output of tail -f /tmp/mypipe to sed to do some post-processing of the messages, but unfortunately some of them are not newline-terminated. This is a problem because it means multiple distinct UDP messages could be on the same line, and also because tail -f /tmp/mypipe | sed ... does not pass the last line if it is unterminated.



Ideally I would like to be able to add a custom message delimiter as they are sent to my pipe, so that I can easily find the message boundaries. If that's not possible then is there some way I can follow this file and pipe the final (potentially unterminated) line to another program for post-processing?









share|improve this question












share|improve this question




share|improve this question








edited Jul 27 at 20:56
























asked Jul 27 at 20:43









abc

284




284











  • I was able to get closer to my goal, though it's not perfect. Neither UDP-LISTEN nor UDP-RECV seemed to work -- when I tried to execute a system command to echo a trailing newline it appears they would hang on cat;. Using UDP-RECVFROM like so seems to work: socat -u UDP-RECVFROM:9999,fork SYSTEM:"cat; echo "n""
    – abc
    Jul 27 at 22:21










  • The solution in my comment above appears to suffer from a race condition -- since the receives are forked (as they have to be, else socat exits after the first UDP message) the SYSTEM commands are not executed atomically. I noticed the cat and echo getting interleaved when multiple messages came in at the same time. I serialized it by wrapping it in a lock like this: socat -u UDP-RECVFROM:9999,fork SYSTEM:"(flock -x 200; cat; echo "n";) 200>./udplockfile"
    – abc
    Jul 27 at 22:43
















  • I was able to get closer to my goal, though it's not perfect. Neither UDP-LISTEN nor UDP-RECV seemed to work -- when I tried to execute a system command to echo a trailing newline it appears they would hang on cat;. Using UDP-RECVFROM like so seems to work: socat -u UDP-RECVFROM:9999,fork SYSTEM:"cat; echo "n""
    – abc
    Jul 27 at 22:21










  • The solution in my comment above appears to suffer from a race condition -- since the receives are forked (as they have to be, else socat exits after the first UDP message) the SYSTEM commands are not executed atomically. I noticed the cat and echo getting interleaved when multiple messages came in at the same time. I serialized it by wrapping it in a lock like this: socat -u UDP-RECVFROM:9999,fork SYSTEM:"(flock -x 200; cat; echo "n";) 200>./udplockfile"
    – abc
    Jul 27 at 22:43















I was able to get closer to my goal, though it's not perfect. Neither UDP-LISTEN nor UDP-RECV seemed to work -- when I tried to execute a system command to echo a trailing newline it appears they would hang on cat;. Using UDP-RECVFROM like so seems to work: socat -u UDP-RECVFROM:9999,fork SYSTEM:"cat; echo "n""
– abc
Jul 27 at 22:21




I was able to get closer to my goal, though it's not perfect. Neither UDP-LISTEN nor UDP-RECV seemed to work -- when I tried to execute a system command to echo a trailing newline it appears they would hang on cat;. Using UDP-RECVFROM like so seems to work: socat -u UDP-RECVFROM:9999,fork SYSTEM:"cat; echo "n""
– abc
Jul 27 at 22:21












The solution in my comment above appears to suffer from a race condition -- since the receives are forked (as they have to be, else socat exits after the first UDP message) the SYSTEM commands are not executed atomically. I noticed the cat and echo getting interleaved when multiple messages came in at the same time. I serialized it by wrapping it in a lock like this: socat -u UDP-RECVFROM:9999,fork SYSTEM:"(flock -x 200; cat; echo "n";) 200>./udplockfile"
– abc
Jul 27 at 22:43




The solution in my comment above appears to suffer from a race condition -- since the receives are forked (as they have to be, else socat exits after the first UDP message) the SYSTEM commands are not executed atomically. I noticed the cat and echo getting interleaved when multiple messages came in at the same time. I serialized it by wrapping it in a lock like this: socat -u UDP-RECVFROM:9999,fork SYSTEM:"(flock -x 200; cat; echo "n";) 200>./udplockfile"
– abc
Jul 27 at 22:43










1 Answer
1






active

oldest

votes

















up vote
3
down vote



accepted










One possibility that does not involve forking is to use the socat verbose output rather than the data. My version of socat -v includes the length of the data in the verbose output, so you know where it ends. For example,



mkfifo mypipe
while sleep 3
do printf "%sNONEWLINE" $RANDOM
done |
socat -u - UDP4:localhost:9999 &
socat -u -v UDP-RECV:9999 - >/dev/null 2>mypipe &
cat -uv mypipe


will output before each data item (eg 9430NONEWLINE) a header starting > with the date and a length.



> 2018/07/28 10:29:33.965222 length=13 from=0 to=12
9430NONEWLINE> 2018/07/28 10:29:36.968335 length=14 from=13 to=26
26947NONEWLINE> 2018/07/28 10:29:39.971025 length=14 from=27 to=40
15126NONEWLINE





share|improve this answer





















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f458951%2fhow-can-i-add-message-delimiters-to-a-udp-stream-socat-is-piping%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    One possibility that does not involve forking is to use the socat verbose output rather than the data. My version of socat -v includes the length of the data in the verbose output, so you know where it ends. For example,



    mkfifo mypipe
    while sleep 3
    do printf "%sNONEWLINE" $RANDOM
    done |
    socat -u - UDP4:localhost:9999 &
    socat -u -v UDP-RECV:9999 - >/dev/null 2>mypipe &
    cat -uv mypipe


    will output before each data item (eg 9430NONEWLINE) a header starting > with the date and a length.



    > 2018/07/28 10:29:33.965222 length=13 from=0 to=12
    9430NONEWLINE> 2018/07/28 10:29:36.968335 length=14 from=13 to=26
    26947NONEWLINE> 2018/07/28 10:29:39.971025 length=14 from=27 to=40
    15126NONEWLINE





    share|improve this answer

























      up vote
      3
      down vote



      accepted










      One possibility that does not involve forking is to use the socat verbose output rather than the data. My version of socat -v includes the length of the data in the verbose output, so you know where it ends. For example,



      mkfifo mypipe
      while sleep 3
      do printf "%sNONEWLINE" $RANDOM
      done |
      socat -u - UDP4:localhost:9999 &
      socat -u -v UDP-RECV:9999 - >/dev/null 2>mypipe &
      cat -uv mypipe


      will output before each data item (eg 9430NONEWLINE) a header starting > with the date and a length.



      > 2018/07/28 10:29:33.965222 length=13 from=0 to=12
      9430NONEWLINE> 2018/07/28 10:29:36.968335 length=14 from=13 to=26
      26947NONEWLINE> 2018/07/28 10:29:39.971025 length=14 from=27 to=40
      15126NONEWLINE





      share|improve this answer























        up vote
        3
        down vote



        accepted







        up vote
        3
        down vote



        accepted






        One possibility that does not involve forking is to use the socat verbose output rather than the data. My version of socat -v includes the length of the data in the verbose output, so you know where it ends. For example,



        mkfifo mypipe
        while sleep 3
        do printf "%sNONEWLINE" $RANDOM
        done |
        socat -u - UDP4:localhost:9999 &
        socat -u -v UDP-RECV:9999 - >/dev/null 2>mypipe &
        cat -uv mypipe


        will output before each data item (eg 9430NONEWLINE) a header starting > with the date and a length.



        > 2018/07/28 10:29:33.965222 length=13 from=0 to=12
        9430NONEWLINE> 2018/07/28 10:29:36.968335 length=14 from=13 to=26
        26947NONEWLINE> 2018/07/28 10:29:39.971025 length=14 from=27 to=40
        15126NONEWLINE





        share|improve this answer













        One possibility that does not involve forking is to use the socat verbose output rather than the data. My version of socat -v includes the length of the data in the verbose output, so you know where it ends. For example,



        mkfifo mypipe
        while sleep 3
        do printf "%sNONEWLINE" $RANDOM
        done |
        socat -u - UDP4:localhost:9999 &
        socat -u -v UDP-RECV:9999 - >/dev/null 2>mypipe &
        cat -uv mypipe


        will output before each data item (eg 9430NONEWLINE) a header starting > with the date and a length.



        > 2018/07/28 10:29:33.965222 length=13 from=0 to=12
        9430NONEWLINE> 2018/07/28 10:29:36.968335 length=14 from=13 to=26
        26947NONEWLINE> 2018/07/28 10:29:39.971025 length=14 from=27 to=40
        15126NONEWLINE






        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jul 28 at 8:34









        meuh

        29k11648




        29k11648






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f458951%2fhow-can-i-add-message-delimiters-to-a-udp-stream-socat-is-piping%23new-answer', 'question_page');

            );

            Post as a guest













































































            e,7kIXI5w1k,n4,GJ,BeGGLBQ,K7hsQ vpzmE3Fi,Eo9Az,n2n3XJ
            SmfU yIYlL4hNRY64PuT nIEtMzYuNOFK0 l9RWiiNYdzoz ghLzNx e,sa6ZZXaf,c7H

            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            How many registers does an x86_64 CPU actually have?

            Displaying single band from multi-band raster using QGIS