Skip to content

Instantly share code, notes, and snippets.

@Integralist
Last active May 5, 2024 18:56
Show Gist options
  • Save Integralist/6c8bfed1550ec8b9933e to your computer and use it in GitHub Desktop.
Save Integralist/6c8bfed1550ec8b9933e to your computer and use it in GitHub Desktop.
Netcat

Install the netcat nc command with Homebrew (otherwise Mac OS X version is really old and the interface is different):

brew install netcat

Use netcat to listen for incoming TCP connections on port 3000:

nc -l -p 3000

Note: old versions of netcat consider using -l and -p incorrect usage
e.g. this would work instead for old versions of netcat nc -l 3000

This instance of netcat is considered a "listener" and is now waiting for a connection.

Once you connect to the listener, the connection will act like a channel/pipe.

Use netcat to establish a TCP connection (run in a new terminal window so as to not conflict with listening netcat instance):

nc localhost 3000

You've set up both ends of the TCP connection. If you type into one of those terminal windows and hit <Enter>, you should see whatever you typed appear in the other window. Any data put through one end of the pipe will appear at the other end of the pipe.

Execute <Ctrl-c> to stop both netcat instances.

Now, to send a HTTP request we'll need two terminal windows again. In the first we'll again be listening on port 3000:

nc -l -p 3000

But this time in the other terminal window we'll use curl to send a HTTP request to our localhost:3000 that netcat has set-up:

curl http://127.0.0.1:3000/

Now in the listening netcat terminal window simply type the following HTML code, then press <Enter> (that's important, it doesn't work otherwise) and then stop the netcat instance by executing <Ctrl-c> to see the HTML response sent back to the other terminal window where you made the initial curl request (you can do this in your browser as well if you want to see the HTML actually rendered):

<h1>hello world</h1>

If you try this from both the terminal and from a proper browser request, you'll notice a slight difference between sending a curl request and sending a HTTP request from your browser:

curl request:

GET / HTTP/1.1
User-Agent: curl/7.37.1
Host: 127.0.0.1:3000
Accept: */*

browser request:

GET / HTTP/1.1
Host: 127.0.0.1:3000
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36
DNT: 1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
@Integralist
Copy link
Author

You can turn netcat into a temporary webserver (you'll need a index.html file):

nc -l -p 8888 < index.html 

Then hit http://127.0.0.1:8888/index.html in your web browser

Note: use a loop for have netcat server indefinitely
while true; do nc -l -p 8888 < index.html; done

@Integralist
Copy link
Author

You can stream files from a listener to a client with netcat:

Listener:

nc -v -w 30 -l -p 8080 < some-file.txt

Client:

nc -v -w 2 127.0.0.1 8080 > stream-content.txt

You'll find that the new file created (stream-content.txt) will contain the contents expected, but also the following additional details provided by netcat:

found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
        outif lo0
        src 127.0.0.1 port 50796
        dst 127.0.0.1 port 8080
        rank info not available
        TCP aux info available

Connection to 127.0.0.1 port 8080 [tcp/http-alt] succeeded!

Note: you can use << and >> to append instead

@jonathanhle
Copy link

This is great - thanks for sharing this publicly

@Integralist
Copy link
Author

@jonathanhle you're very welcome 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment