Adding SO_REUSEADDR and Helpful Debugging to Exceptions

### Socket Reuse

The first thing I've put in the code is to _always_ set SO_REUSEADDR to true by calling `setReuseAddress(true)` _before_ the call to `bind()`. The purpose of this is to make sure that we don't have problems when programs quickly restart and have a socket left in the 'open' state and unavailable for re-use.

### Helpful Exceptions

When there's a `BindException` thrown, let's indicate if it was the _local endpoint_ or the _remote endpoint_ by placing the host and port in the exception message and adding the for "to" for the remote endpoint and "on" to the local endpoint. This makes it very clear what the problem was, and where it was _trying_ to connect.

This doesn't change the outcome of the exception, but it makes debugging so _much_ easier.