Listener refactor

### Motivation:
It turns out everyone uses `TransportLayer` as a dump for every method or attribute whose proper place is undetermined. As a result, this class is bloated with all sorts of code: managing sockets, listening for requests and handling various pieces of crypto code.

This is the first of a series of attempts to reduce the bloat of `TransportLayer` and factor the code into several smaller and simpler classes, more amenable to testing and maintenance.

The new `Listener` classes mirror the pattern of `PeerSender` and `CryptoPeerSender` but are designed cleanly and follow good practices such as defining all members in constructors. They are also completely independent from `dht.py` and `transport.py`, whereas `Sender` classes still have this problem and should be refactored in the future.

### Changelog:
* Factor classes `PeerListener` and `CryptoPeerListener` out of `TransportLayer` and `CryptoTransportLayer`, respectively.
* As the `Sender` classes get a `dict` that is then encrypted, compressed and sent, the listener classes do the inverse actions and receive, decompress and decrypt the messages, relaying the sent `dict`s to the receiver.
is there some sort of printStackTrace() in python?

maybe we should have an error printer somewhere in utils for when you don't really know what error will be thrown, and have it printed nicely both in stdout and the logs (if a log object is available)

I'm thinking something like

```def print_error(error_object, dump_stacktrace=False, logger=None, ):
  '''by default prints error message in stdout. 
    message includes stack trace if dump_stacktrace to True
   message is used by logger object if passed.
   ...
```