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.

Other than allowing callers to enable and disable retry delays, this
doesn't affect the public API.