15

I'd like to take a program P that reads from stdin & writes to stdout, but connect it to nc or whatever such that it reads from a certain port and outputs to another port.

# The reading is easy, here P reads from port 50505
nc -l 50505 | P

How do I get it to write back to say port 60606?

Yimin Rong
  • 913
  • 2
  • 9
  • 23
  • Your question is unclear as stated. You mean that someone may open 2 TCP connections to your machine, one to port 50505 and another to port 50506, send data on the first one intended to be fed to `P` and expect to read the output of `P` from the second TCP connection? Why the UDP tag? – Stéphane Chazelas Nov 10 '14 at 21:52
  • Yes! As far as `UDP`, I think I wanted `ports`, but that wasn't an existing keyword, so I thought `TCP`, and I think I added `UDP` out of reflex. – Yimin Rong Nov 10 '14 at 22:03
  • See [Can I pipe/redirect a console application through netcat so it can be used remotely?](http://superuser.com/q/607783/150988) (on SU). – Scott - Слава Україні Nov 10 '14 at 22:18

2 Answers2

17

I you mean that someone may open 2 TCP connections to your machine, one to port 50505 and another to port 60606, send data on the first one intended to be fed to P and expect to read the output of P from the second TCP connection, then that would be:

< /dev/null nc -q -1 -l 50505 | P | nc -l 60606 > /dev/null

Or with socat:

socat -u tcp-listen:50505,reuseaddr - | P | socat -u - tcp-listen:60606,reuseaddr

For P to send its output back to the same connection:

socat tcp-listen:50505,reuseaddr exec:P
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • If you want `socat` to connect to a remote host instead of listening for an incoming connection, replace `tcp-listen:PORT` with `tcp:HOST:PORT` – Michael Mrozek Dec 25 '20 at 05:45
3

You don't need nc in order to work with ports. bash can do that itself:

Bash handles several filenames specially when they are used in redirections, as described in the following table:

/dev/fd/fd
    If fd is a valid integer, file descriptor fd is duplicated.
/dev/stdin
    File descriptor 0 is duplicated.
/dev/stdout
    File descriptor 1 is duplicated.
/dev/stderr
    File descriptor 2 is duplicated.
/dev/tcp/host/port
   If host is a valid hostname or Internet address, and port is an integer 
   port number or service name, bash attempts to open a TCP connection to
   the corresponding socket.
/dev/udp/host/port
    If host is a valid hostname or Internet address, and port is an integer 
    port number or service name, bash attempts to open a UDP connection to
    the corresponding socket.
Hauke Laging
  • 88,146
  • 18
  • 125
  • 174
  • 3
    `/dev/tcp` is often disabled and can't be used for _listening_. You need `zsh` if you want a shell that can create listening tcp sockets. – Stéphane Chazelas Nov 10 '14 at 22:30
  • @StéphaneChazelas I have to admit I never tried. It doesn't say anything about this restriction in the man page, does it? – Hauke Laging Nov 10 '14 at 22:51
  • Well, how would you do it? A listener socket is a door to create more accepting sockets, redirections don't work as well for that. zsh uses a builtin for that (`ztcp -l` for listening and `ztcp -a` to accept connections on the listening socket). – Stéphane Chazelas Nov 10 '14 at 23:02