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

Update: I've isolated the problem to when the stream gets written to $buf1. I wrote <$lstream1> out and it had just x0As. After $buf1 = <$lstream1> then there were the incorrect x0D x0As. Any recommendations on using this buffer??

I have written a proxy that forwards data it receives to connected clients. It is written in ActivePerl running on a Windows system. When it receives a line feed (0A) character it writes out a carriage return (0D) and a line feed (0A). I need the input unmodified (ie just OA). How do I suppress the OD? I thought using binmode ($fh, ":raw") was supposed to help with this. Any thoughts? Here is the portion that handles receiving the stream and sending to all connected clients...
sub stream1 { my ($lstream1) = @_; #socket data comes in on my $buf1; #buffer receiving stream if($lstream1->connected) { while(defined($buf1=<$lstream1>)) { #PROBLEM foreach my $fn (@stream1_clients) { #all connected clients open my $fh, ">&=$fn" or warn $! and die; #open socket to cli +ent binmode($fh, ":raw"); #thought this solved win/unix problems print $fh $buf1; } $|++ } } my $stream_ip = $lstream1->peerhost; print "* Stream 1 [$stream_ip:$stream1_prt] disconnected\n"; close($lstream1); }

Replies are listed 'Best First'.
Re: Remove extra carriage return (0D) on socket communications
by roboticus (Chancellor) on Nov 11, 2011 at 15:56 UTC

    PhillyR:

    binmode simply tells perl not to change any of the bytes in the stream. If the other side of your pipe is putting in the carriage returns, then binmode isn't going to take them out. If you can use binmode on the other end of the pipe that should solve your problem. If not, you'll have to strip them out.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Remove extra carriage return (0D) on socket communications
by Marshall (Canon) on Nov 11, 2011 at 23:32 UTC
    I'm not sure that what you have is a Windows vs Unix problem. Standard network termination is 0D0A (like how a Windows box likes to do). So even if 2 Unix boxes were talking in a text mode over a socket, the data over the socket would be CRLF terminated instead of the normal LF like to a terminal/local file. So, on the Unix box, print() does different things depending upon whether it is talking to a network connection or a local file on a Unix box.

    I think you are going to wind up using read() and write() instead of print() if you want absolute control of exactly what is sent over the socket. In that case, you would be taking on the job of figuring out what a "line" is.

      I'm not sure that what you have is a Windows vs Unix problem.

      Agreed.

      But the simplest solution would probably be to use the :crlf IO layer on the socket handle(s). Then print and readline should do the right thing, just as they do for the windows filesystem.


      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.
Re: Remove extra carriage return (0D) on socket communications
by Anonymous Monk on Nov 11, 2011 at 15:55 UTC

    Maybe a dumb question, but did you use binmode on both the input and the output? I only see one open in that code.

      Not a dumb question. I just added binmode every time I declared a socket or accepted a new socket from a listen socket....
      Still get 0D 0A!!
Re: Remove extra carriage return (0D) on socket communications
by johnny_carlos (Scribe) on Nov 11, 2011 at 16:30 UTC
      I'm looking at this. Not sure I understand how I would use. Something like the following:
      open my $fh, ">&=$fn:bytes" or warn $! and die; #open socket to clien +t
        PhillyR I'm sorry, my documentation link didn't go to the correct place. This is what I meant

        It's a pragma, so you'd put it at the top of you code, like "use strict;"