Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Setting Up a TCP Listener and Connecting to It with Netcat

setting-up-a-tcp-listener-with-connecting-to-it-with-netcat.jpg

This can be handy to test connecting to a specific port.

Quick Jump:

The nc command (Netcat) lets us start a TCP listener and connect to it. If you’re developing a tool or testing something that connects to a TCP port, nc lets you quickly do that. It can do a lot more than that, but that’s the use case we’re going to cover in this post.

Before we get into the examples it’s worth pointing out there’s 3 variants of nc such as “traditional”, “GNU” and “OpenBSD”. They all act a little different, some variants are more maintained than others.

Typically most folks choose between traditional or OpenBSD because it’s available in most package managers. Both versions are available on Linux and macOS.

Ubuntu installs the OpenBSD version by default. Debian requires that you pick which version to install, such as sudo apt-get install netcat-openbsd. Generally speaking, the OpenBSD version is considered to be more common.

All of the examples below are using the OpenBSD version. If you notice the outputs look different or certain flags don’t work you probably have a different variant of Netcat. If nc -e fails with “invalid option” then you have the OpenBSD version (a good thing IMO).

# Listening and Connecting

Listening:
$ nc -v -l 4299
Listening on 0.0.0.0 4299
  • -v provides more verbose log output (such as showing “Listening on…” above)
  • -l listens for an incoming connection
  • 4299 is the port to listen on, feel free to change it to any other available port
  • You can also do localhost 4299 or another IP address or hostname before the port
    • As seen above, if you omit that it defaults to 0.0.0.0
Connecting:
$ nc -v localhost 4299
Connection to localhost (127.0.0.1) 4299 port [tcp/*] succeeded!

The connection will remain open until you kill it, such as hitting CTRL+c.

  • By omitting -l we’re saying we want to connect not listen
  • -v provides more verbose log output (such as “Connection to…” above)
  • We need to supply a host to connect to, in this case localhost
  • 4299 is the port to connect to, in our example it should match the listener port

Our listener will also log Connection received on localhost 54658. That port number on the end will be different since it’s a randomly assigned port.

# Experimenting

You’re not limited to connecting to TCP listeners that nc created.

For example, I typically run web apps locally on port 8000. If I start one of those projects and run nc -v localhost 8000 then it will make a successful connection. That’s because HTTP is based off TCP.

Also, if you run nc -v localhost 50001 or pick a port with no active TCP listener then you’ll get a connection refused error. That’s normal.

Lastly, here’s a fun one. If you run nc -v -l 4299 twice you will be able to listen on the same port. Then if you connect with nc -v localhost 4299 one of them will receive the connection.

If you have a socket analysis tool installed such as ss you can verify that:

$ ss -ntpl | grep 4299
LISTEN 0      1            0.0.0.0:4299       0.0.0.0:*    users:(("nc",pid=32725,fd=3))
LISTEN 0      1            0.0.0.0:4299       0.0.0.0:*    users:(("nc",pid=32720,fd=3))

That likely breaks your mental model of how ports work right? You can’t listen on the same port twice. That’s what I thought too but it’s more detailed than that. The rule is really you can’t bind to the same combination of a few different values that are included as part of the TCP connection.

This starts to get a bit below my understanding of how sockets work but this StackOverflow answer has a complete breakdown if you want to know the gory details.

# Demo Video

Timestamps

  • 0:21 – Traditional vs GNU vs OpenBSD
  • 1:36 – Creating a listener
  • 2:32 – Connecting to our listener
  • 3:46 – Connecting to an existing port such as an HTTP port
  • 4:42 – Accessing an unused port
  • 4:53 – Listening on the same port twice?
  • 6:29 – Checking out port usage with ss

When did you last use Netcat? Let us know below!

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments