Where to start First steps track · 15 stages
Linux Labs

nc — checking ports and transferring data

4 min netcat (openbsd/ncat)

Checking whether ports are reachable, simple data transfer over TCP/UDP.

Cheat sheet

6 commands Printable version
  • nc -zvw3 host 22 is the port open? (refused vs timed out)
  • nc -zvu host 53 UDP
  • nc -zv host 20-25 a range
  • nc -l 9000 listen (a test server)
  • echo data | nc host 9000 send
  • nc -l 9000 > out.bin receive a file (on the other side — nc host 9000 < file.bin)

Overview

nc (netcat) is the TCP/UDP "Swiss Army knife": check whether a port is open, send raw data, spin up a temporary listener, move a file between machines.

bash
nc -zv host 22                    # check whether port 22 is open (z=scan, v=verbose)
nc -zv host 80 443                # several ports at once

On Ubuntu this is usually netcat-openbsd (options as below). There's also a ncat variant (from nmap) with similar syntax.

Options

8
Option Meaning
-z scan mode: only check, don't send data
-v verbose output (refused / open / timed out)
-u UDP instead of TCP
-l listen (server mode)
-p N the local port
-w N connection timeout, in seconds
-n skip DNS resolution (faster)
-k (with -l) don't close after one client
Option What it does Example
-z Scan mode — only check reachability, do not send data. nc -zv host 22
-v Verbose output — refused, open, timed out. nc -zv host 80
-l Listen for an incoming connection (server mode). nc -l 9000
-w N Connection timeout in seconds — keeps the command from hanging forever. nc -zvw3 host 22
-u Use UDP instead of TCP. nc -zvu host 53
-n Do not resolve DNS names — faster and more reliable for checks. nc -zvn 10.0.0.5 22
-p N Use a specific local port. nc -p 5000 host 9000
-k With -l — keep listening after one client disconnects. nc -lk 9000

Nothing found. Try a shorter query.

Recipes

2

Checking ports

bash
nc -zv 10.0.0.5 5432             # is the postgres port reachable from this machine
nc -zvw3 host 22                 # with a 3s timeout (don't hang)
nc -zvu host 53                  # a UDP port (DNS)
nc -zv host 20-25                # a range of ports
for p in 80 443 5432; do nc -zvw2 host $p; done   # a list of ports

Distinguish the responses: succeeded/open — the port is listening; Connection refused — reached the host, but nothing is listening; timed out — never reached it (firewall/routing).

Data and transfer

bash
nc -l 9000                        # listen on port 9000 (a simple test server)
echo "hello" | nc host 9000       # send a string
printf 'GET / HTTP/1.0\r\n\r\n' | nc host 80   # a raw HTTP request
nc -lk 9000                       # keep listening after a client disconnects

# transfer a file (receiver, then sender):
nc -l 9000 > out.bin              # on the receiver
nc host 9000 < file.bin           # on the sender

# a simple "chat"/two-way channel to test connectivity:
nc -l 9000        # server   |   nc host 9000   # client

Troubleshooting

4

"Is this port reachable from here?"

nc -zvw3 host port. refused is not the same as timed out: the first means the service isn't running/it's the wrong port (the network is fine); the second means it never got there (firewall/routing). This is the key distinction.

The port is open locally, but not from outside

On the server, nc -zv 127.0.0.1 8080 checks whether it's listening. If yes, but there's a timeout from outside, the issue is the bind address (0.0.0.0 vs 127.0.0.1) or the firewall (see ss, firewall).

You need a quick L4 connectivity check between hosts

nc -l 8080 on one side, nc -zv host 8080 on the other — does TCP/UDP get through on that exact port (useful when debugging a firewall).

nc "hangs"

Without -w, a connection can wait forever. Add a timeout (-w3), and -z for a clean check with no data exchange.

See also

  • ss — Who's listening on what ports and which connections are open — the modern netstat.
  • curl — HTTP/HTTPS requests from the CLI — debugging APIs and web services, headers, methods.
  • tcpdump — Packet sniffing for diagnostics — filters by host, port, interface.
Loading…