Add a dynamic receiver class for more flexible packet handling It's useful for middleware libraries which may not know all packet types at compile time, or if different packets need to be routed to different receivers.
Remove function overloads for manually specifying packet IDs Since the IDs can be transposed when sending and receiving, this isn't terribly useful anymore. For Communicator's multi-protocol support having abnormally high packet IDs is detrimental.
Redesign Communicator to support multiple protocols This makes it easier for a library to provide a base protocol and allow applications to add their own protocols on top. It's also used for the Communicator's internal handshake protocol.
Decorate things which constitute the public API
Check for EOF return before checking for errors The check_sys_error function converts errors from non-blocking operations which would block into a zero return, making them indistinguishable from a zero return due to the other end closing the connection.
Include the matching header first in .cpp files This avoids accidentally using transitively included headers.
Use std::unique_ptr for owning pointers
Refactor the API for defining packets in Protocol A variadic template function provides a nicer interface than chained call operators. Required C++ standard version is now C++14 due to deduced automatic return types.
Use nullptr instead of 0 for pointers