I’m not a “network guy.” I still don’t know what exactly the subnet mask means, and I am often thankful that OS X is so willing to automatically configure network settings for me well.
That said, recently I’ve been finding myself doing a lot of programming with sockets. They provide a low-level network interface to communicate between computers, and are used like other file descriptors. On the C side of things there’s a little more work than I’d like, and as such, I’ve found Python an invaluable tool.
In fact, I think any time you’re working with a new concept, technique or algorithm it’s extremely helpful to use a scripting language. Like others, Python offers an interactive session where you can develop code fragments by trial and error with each step, rather than trying to debug a chunk of code you’ve written with only a vague notion of what’s going on behind the scenes. It allows you to pause between steps and see the effects and results of each function.
Interestingly enough, another tool has come in extremely handy - netcat. It’s designed to print to stdout everything that it hears on the socket, and then it sends everything it receives on stdin through the socket. It allows you to examine some of the specifics of a protocol without worrying about the details of your own code or whether or not your code works. Netcat is tried and true, and will tell you exactly what’s happening.
This all came up in the context of WebSockets. They’re a part of the HTML5 spec and provide a JavaScript interface for real socket communication (there are of course some caveats, especially with respect to how to handle binary data). We’ve been using them for a project where we’d like the client to not need a special program to interact with a piece of software, and so instead implemented the protocol in JavaScript.
There was, however, some trouble at the offset. I had a bit of difficulty finding out why exactly the WebSocket client would seem to start to make a connection but then immediately complain about handshakes. What would have been much easier is to just open up netcat on the same port and have a conversation with the WebSocket itself.
1 2 3 4 |
|
And then try to make a connection from the JavaScript side
1 2 3 4 5 |
|
I had figured (incorrectly) that WebSockets would work in essentially the exact same way that sockets would. This is what we’d then expect to receive:
1 2 3 4 5 |
|
It was only after realizing that this is what the WebSocket was sending that it became clear that the reason that no connection was actually happening was because the browser wasn’t getting the rest of the handshake:
1 2 3 4 5 6 |
|
Oddly enough, I can’t seem to get netcat to play nice sending the response code, but it can easily-enough give us an indication of what was happening at first. Python can handle the rest for us:
1 2 3 4 5 6 7 8 9 10 |
|
And notice that it’s not until the listening socket sends its response portion of the handshake that the JavaScript console will print the “hello” we told it to upon opening the connection. Now that we have the two talking, let’s actually send and receive a couple of messages:
1 2 |
|
And then we receive the message in Python:
1 2 |
|
And here we find another oddity of WebSockets. All messages seem to be prepended with \x00 and appended with \xff (though this is also mentioned in the specification). If we try to send a message from Python without these two extra characters, we’ll get nothing out on the JavaScript side (go ahead and give it a try!):
1 2 3 4 |
|
Of course I’m sure there are other robust tools the real “networking guys” use to make their lives easier. But outside of pulling up WireShark or trying to figure this out by writing C code, netcat and Python definitely saved the day.