help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: plz help with tcpserver


From: Alex fxmbsw7 Ratchev
Subject: Re: plz help with tcpserver
Date: Mon, 26 Jul 2021 22:32:08 +0200

sorry, run my gawk, not awk
i didnt write sh, did i

or at least as i did with -v RS=\\n\\n

in the end my gawk, to explain, merges two following newlines to one,
in a print process, this is short to test, and it failed
so its a gawk bug ?

On Mon, Jul 26, 2021 at 10:27 PM Greg Wooledge <greg@wooledge.org> wrote:
>
> On Mon, Jul 26, 2021 at 09:46:38PM +0200, Alex fxmbsw7 Ratchev wrote:
> > > term 1
> > > tcpserver 0 2000 strace -f gawk -v RS=\\n\\n 1 &
> > >
> > > strace for seeing weirdness
> > > then
> > > term 2, no printf or pipe, non eof input
> > > cause, http clients dont end conn after printing req headers
> > > ( nc 0 2000 to connect via netcat .org or so telnet client to localhost 
> > > port 2000 )
> > >
> > > nc 0 2000
> > >
> > > then see strace began to show, read(
> > >
> > > then enter newlines some, it never prints, till control-c of nc
> > > and result, the printed input, wont ever be recieved
>
> Pretend for a moment that the reader has no idea what "gawk -v RS=\\n\\n 1"
> is supposed to do.
>
> Let's first verify how our tools actually *work*, shall we?  I don't
> think you've programmed correctly for the line ending issue.
>
> ===== BEGIN EXAMPLE ONE =====
> term1> tcpserver 0 2000 bash -c 'while read -r; do printf "Got: <%s>\n" 
> "$REPLY"; done'
>
> term 2> telnet localhost 2000
> ... Escape character is '^]'.
> hello
> >ot: <hello
> goodbye
> >ot: <goodbye
> ===== END EXAMPLE ONE =====
>
> What happened?  The lines that I typed interactively in telnet were
> received and processed in real time by the program that tcpserver
> launched, which is good.  But there's an obvious carriage return issue
> going on there.  You can see it by the greater-than signs overwriting
> the first character of the line, instead of being at the end of the line.
>
> Remember, when you receive lines of text from a network socket, they may
> be encoded with CR-LF line ending characters.  They're "supposed" to be
> that way, because that's the "standard".  And it appears that telnet on
> my system is enforcing that standard.
>
> We can verify that it's telnet doing so, and not tcpserver, by running
> another experiment.
>
> ===== BEGIN EXAMPLE TWO =====
> term1> same as before
>
> term2> { echo hello; sleep 1; echo goodbye; } | nc -N localhost 2000
> Got: <hello>
> Got: <goodbye>
> ===== END EXAMPLE TWO =====
>
> That looks like what I was expecting to see!  So, we can conclude that
> telnet was adding carriage returns to what I was typing, but nc -N
> (using the implementation of nc on my system -- remember, nc is NOT
> standard, and there are numerous variants of it out there) passed the
> input through without modification.
>
> So, let's rewrite our server side, to handle the possible presence of
> carriage returns in the input.  This is a pain in the ass to write as
> a shell one-liner with bash -c, so I'll use a script.
>
> ===== BEGIN EXAMPLE THREE =====
> term1> cat foo
> #!/bin/bash
> while read -r; do
>   REPLY=${REPLY%$'\r'}
>   printf 'Got: <%s>\r\n' "$REPLY"
> done
> term1> tcpserver 0 2000 ./foo
>
> term2> telnet localhost 2000
> ... Escape character is '^]'.
> hello
> Got: <hello>
> goodbye
> Got: <goodbye>
> ===== END EXAMPLE THREE =====
>
> All is well.  Now we know that two combinations of tools
> (tcpserver, bash, telnet) and (tcpserver, bash, nc -N) both work fine.
>
> Now let's introduce awk.  Since I don't know what your thing does or is
> trying to do, I'll try to duplicate the bash script that I just wrote,
> using awk.  Let's start out simple:
>
> ===== BEGIN EXAMPLE FOUR =====
> term1> tcpserver 0 2000 awk '{print "Got <" $0 ">"}'
>
> term2> telnet localhost 2000
> ... Escape character is '^]'.
> hello
> goodbye
> ^]
> telnet> q
> ===== END EXAMPLE FOUR =====
>
> Well, that was a complete failure, wasn't it?  Maybe that just
> demonstrates that I don't know awk very well.  Maybe it's a buffering
> thing (BashFAQ 009).  The FAQ page says that for gawk, we have to use
> the fflush() function.  So let's try again:
>
> ===== BEGIN EXAMPLE FIVE =====
> term1> tcpserver 0 2000 awk '{print "Got <" $0 ">"; fflush()}'
>
> term2> telnet localhost 2000
> ... Escape character is '^]'.
> hello
> >ot <hello
> goodbye
> >ot <goodbye
> ===== END EXAMPLE FIVE =====
>
> Looks familiar!  My awk program isn't handling the carriage returns from
> telnet correctly.  That's a bug -- not in awk, but in my program, because
> a network service has to be able to handle them.  They may be there, or
> they may not.  But the good news is that, apart from the CR issue, it
> worked as expected.
>
> Now let's move on to nc -N.
>
> ===== BEGIN EXAMPLE SIX =====
> term1> same as above
>
> term2> { echo hello; sleep 1; echo goodbye; } | nc -N localhost 2000
> Got <hello>
> Got <goodbye>
> ===== END EXAMPLE SIX =====
>
> Looks reasonable to me.
>
> Well, you're the awk guy, not me, so you can take it from here.  Figure
> out how to write your program so that it correctly handles CR-LF or LF
> line endings, use the fflush() command, and use nc -N on the client side if
> you're on the same version of netcat that I am (netcat-openbsd 1.217-3).
> Or if you're on a different version of netcat, figure out how to make yours
> close cleanly when stdin hits EOF.
>
> Good luck.
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]