Netcat Cheatsheet
Listener Mode
Use this Netcat reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Binding a port
nc -l 8080 # OpenBSD nc, macOS nc, Ncat nc -l -p 8080 # netcat-traditional, GNU netcat, BusyBox nc -lvnp 8080 # verbose, no DNS, the habitual form
The -p difference is the single most common paste failure. OpenBSD nc
takes the port as a positional argument and rejects -p with -l.
netcat-traditional requires -p. Ncat accepts both. If nc -l -p 8080
errors with "cannot use -p and -l", you are on OpenBSD nc, so drop the -p.
| Flag | Effect |
|---|---|
-l | Listen instead of connect |
-k | Keep listening after a client disconnects |
-v | Print each connection as it arrives |
-n | No reverse DNS on the client address |
-s addr | Bind one interface only, instead of all of them |
-u | UDP listener |
-w n | Give up after n seconds with no connection |
One connection, then exit
Plain -l accepts exactly one client and exits when it disconnects. That is
usually a feature, because a one-shot listener is a clean test target.
# Terminal 1 nc -lv 8080 # Terminal 2 echo "hello" | nc 127.0.0.1 8080
Terminal 1 prints hello and then both processes exit. To stay up for a
second client:
nc -lkv 8080 # OpenBSD nc, Ncat ncat -lkv 8080 # same, explicit
netcat-traditional and GNU netcat have no -k. Loop in the shell instead:
while true; do nc.traditional -l -p 8080; done
-k in Ncat handles clients sequentially by default. For concurrent
clients add -m:
ncat -lk -m 20 8080 # up to 20 simultaneous connections
Binding addresses and permissions
nc -l 8080 # all interfaces, 0.0.0.0 and often :: nc -l -s 127.0.0.1 8080 # loopback only, not reachable off-box nc -l -s 10.0.0.7 8080 # one specific interface sudo nc -l 80 # ports below 1024 need root
| Symptom | Cause |
|---|---|
Permission denied | Port below 1024 without root |
Address already in use | Something is bound there already |
| Works locally, not remotely | Bound to 127.0.0.1, or a firewall |
| Client connects, sees nothing | Expected, the listener sends only what you type |
Find what holds the port:
ss -ltnp 'sport = :8080' # Linux lsof -nP -iTCP:8080 -sTCP:LISTEN # macOS and Linux
A listener that exits leaves the port in TIME_WAIT briefly, so an
immediate rebind can fail for up to a minute. Wait, or use a different port.
Serving a fixed response
A listener is a pipe, so redirect a file into it. This is the fastest possible stub server.
# Send a file's contents to whoever connects, once nc -l 8080 < response.txt # A real HTTP response, headers and all printf 'HTTP/1.1 200 OK\r\nContent-Length: 3\r\nConnection: close\r\n\r\nhi' \ | nc -l 8080 # Serve the same response to every client, forever while true; do printf 'HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok' | nc -l 8080 done # Ncat, keeps listening and re-reads the file each time ncat -lk 8080 --send-only < response.txt
Content-Length must match the body byte count exactly or the client hangs
waiting for the rest. Connection: close lets the client know the response
ended, which matters when you get the length wrong.
Capturing what a client sends
Debugging a webhook, an agent, or a misconfigured client: point it at a netcat listener and read the raw bytes.
# Print the request, headers and body nc -lv 8080 # Save it and also watch it nc -lv 8080 | tee /tmp/request.txt # Accept, log with a timestamp, keep listening while true; do echo "--- $(date -Is) ---" nc -l 8080 done | tee -a /tmp/requests.log # Ncat logs the session itself, no shell plumbing ncat -lk 8080 -o /tmp/session.log # plain text ncat -lk 8080 -x /tmp/session.hex # hex dump
Most HTTP clients wait for a response and will report a timeout, but you
still see the full request first, which is the point. To make the client
happy, send a minimal 200 back as shown above.
Chat and broker modes
Two listeners plus a client is enough for a two-way channel, and Ncat has purpose-built modes.
# Bidirectional: both sides type, both sides see it nc -l 8080 # host A nc hostA 8080 # host B # Ncat relays between every connected client ncat --broker -lk 8080 # Ncat's chat server, prefixes messages with a user id ncat --chat -lk 8080
--broker is the useful one. Every client connected to the same broker sees
what every other client sends, so it is a throwaway message bus for testing
without deploying anything.
Access control
Only Ncat can filter who connects, which is a real reason to prefer it for a listener exposed beyond loopback.
ncat -lk 8080 --allow 10.0.0.5 ncat -lk 8080 --allow 10.0.0.0/24 ncat -lk 8080 --allowfile /etc/ncat.allow ncat -lk 8080 --deny 10.0.0.99
| Option | Effect |
|---|---|
--allow <hosts> | Only these may connect, everything else refused |
--allowfile <f> | One host or CIDR per line |
--deny <hosts> | Blocklist, everything else allowed |
--denyfile <f> | Blocklist from a file |
Plain nc -l accepts anything that reaches the port. A netcat listener
has no authentication and no encryption, so bind it to 127.0.0.1 unless
you have a specific reason not to, and never leave one running.
Listener checklist
| Want | Command |
|---|---|
| One-shot test target | nc -lv 8080 |
| Persistent target | nc -lkv 8080 |
| Loopback only | nc -lv -s 127.0.0.1 8080 |
| Log the client's bytes | nc -lv 8080 | tee /tmp/r.txt |
| Fixed HTTP 200 reply | printf 'HTTP/1.1 200 OK\r\n\r\n' | nc -l 8080 |
| Concurrent clients | ncat -lk -m 20 8080 |
| TLS listener | ncat -lk --ssl 8443 |
| Restrict by source | ncat -lk 8080 --allow 10.0.0.0/24 |
| Old netcat, keep alive | while true; do nc -l -p 8080; done |