Implement transparent error handling.

Connections to the server are made as required.  If an error occurs,
behave as though we're talking to a server with no memory, so all
gets return no data.  Reconnect to the server automatically, optionally
delaying to avoid spamming servers with TCP connection requests while
they're down.

This avoids every user of the library needing to roll their own
error handling and reconnection logic.

Internally, this is implemented by making writes no-ops, and responses
return an error code 'server_disconnected'.  This allows the various
callers to _get_response to have a minimum of changes.

This also fixes an assertion failure triggering if the server
disconnects during a request.  There should probably be a test
for this, but it's tricky to write and the reconnection tests
took too long to implement already...

Other than allowing callers to enable and disable retry delays, this
doesn't affect the public API.