nc: Send Data and Grab Service Banners
Piping data into nc sends it over a raw TCP connection and prints whatever the server replies, with no protocol of its own.
When a port is open but the service misbehaves, nc lets you speak the protocol by hand: send a raw HTTP request or read a daemon banner to confirm what is actually listening.
What it does
nc connects to host:port and wires stdin to the socket and the socket to stdout. Anything you pipe in is sent verbatim; anything the server sends back is printed. Because it adds no framing, it is a pure transport for probing text protocols.
Common usage
# raw HTTP request to inspect headers a curl might hide
printf 'GET / HTTP/1.0\r\nHost: api.internal\r\n\r\n' | nc api.internal 80
# read an SMTP or Redis banner
nc -w 2 mail.internal 25 </dev/null
echo -e 'PING\r' | nc -w 2 localhost 6379Options
| Flag | What it does |
|---|---|
| -w <secs> | Timeout for connect and for idle reads |
| -q <secs> | GNU nc: quit N seconds after stdin closes (EOF) |
| -N | OpenBSD nc: shut down the socket on stdin EOF |
| -C | Send CRLF as line endings (handy for HTTP/SMTP) |
In CI
nc can hang waiting for more data after the response arrives. On OpenBSD nc add -N so it closes after stdin EOF; on GNU/traditional nc use -q 1 or -w to bound the read. Use printf with explicit \r\n rather than echo for protocols that require CRLF.
Common errors in CI
A command that never returns is almost always missing -N (OpenBSD) or -q (GNU): nc keeps the half-open socket waiting. An empty reply on an HTTP port usually means you sent HTTP/1.1 without a Host header, or LF where the server requires CRLF.