4

Say I write to a netcat connection:

tail -f ${file} | nc localhost 7050 | do_whatever | nc localhost 7050

what happens here is that we have two socket connections, to do some request/response. But that's not ideal for a few reasons.

What I am looking to do is reuse the same connection, to read from and write to.

Does anyone know how I can reuse just one netcat connection?

6
  • if do_whatever receives a certain message, it will write back to a tcp server, using the second connection. The main problem is that when other processes want to communicate with this one, they will potentially see two connections, instead of one, to communicate with. Commented Apr 21, 2018 at 6:55
  • the only thing I know of is this technique: xmodulo.com/tcp-udp-socket-bash-shell.html Commented Apr 21, 2018 at 7:02
  • You might be able to do it using a coprocess. But this is not the kindof thing that shell scripts are good for. Why not use a language with a sockets API? Commented Apr 21, 2018 at 7:10
  • I have to google what coprocess is...I added an answer which I think should work fine, not sure why I didn't think of it earlier Commented Apr 21, 2018 at 7:39
  • gnu.org/software/bash/manual/html_node/Coprocesses.html Commented Apr 21, 2018 at 7:40

3 Answers 3

6

The correct way to do this in UNIX is to make use of a back pipe. You can do so as follows:

First, create a pipe: mknod bkpipe p

This creates a file named bkpipe of type pipe.

Next, figure out what you need to do. Here are two useful scenarios. In these, replace the hosts/addresses and port numbers with the appropriate ports for your relay.

To forward data sent to a local port to a remote port on another machine:

 nc -l -p 9999 0<bkpipe | nc remotehost 7000 | tee bkpipe

To connect to another machine and then relay data in that connection to another:

 nc leftHost 6000 0<bkpipe | nc rightHost 6000 | tee bkpipe

If you simply need to handle basic IPC within a single host, however, you can do away with netcat completely and just use the FIFO pipe that mknod creates. If you stuff things into the FIFO with one process, they will hang out there until something else reads them out.

Sign up to request clarification or add additional context in comments.

3 Comments

Not sure if it matters, but in my case, only one machine is being used, just localhost. I am using TCP for IPC here.
Well, you can do that... Or you could just use a FIFO pipe for the entire thing. I had the impression that you were using a nectay relay between hosts.
I've added a revision to that effect.
1

Yeah, I think the simplest thing to do is use this method:

tail -f ${file} | nc localhost 7050 | do_whatever > ${file}

just write back into the same file (it's a 'named pipe').

As long as your messages are less than about 500 bytes, they won't interleave.

11 Comments

What does that have to do with the question? I thought this was about writing to the network connection, not the file.
the OP is about reading and writing to the same tcp connection
using the method in this answer, that has been realized
I see what you're doing. Since you can't read back from the network, you're writing to the file that tail -f is reading file.
yeah exactly - I got the answer from here: unix.stackexchange.com/questions/439081/…
|
1

Using ncat is much easier and understandable for beginners as a one-liner ;)

prompt$> ncat -lk 5087 -c ' while true; do read i && echo [You entered:] $i; done'

Connect with telnet (or nc) to localhost port 5087, and everything you type echoes back to you ;) Use -lk option for listening and keeping/maintaining (multiple) connections.

You can make one bash script out of it like this, using back slashes but it invokes multiple bash, not cheap on resource usage:

#!/bin/bash
# title          : ncat-listener-bidirectional.sh
# description    : This script will listen for text entered by a client 
#                  like for instance telnet
#                  and echo back the key strokes
#
ncat -lk 5087 -c ' \
#!/bin/bash \
while true; do  \
  read i && echo [You entered:] $i; \
done'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.