1. Use uctypes.bytearray_at().
Implementation of the "ffi" module predates that of "uctypes", so
initially some convenience functions to access memory were added
to ffi. Later, they landed in uctypes (which follows CPython's
ctype module).
So, replace undocumented experimental functions from ffi to
documented ones from uctypes.
2. Use more suitable type codes for arguments (e.g. "P" (const void*)
instead of "p" (void*).
3. Some better var naming.
4. Clarify some messages printed by the example.
Per new conventions, we'd like to consistently use "u*" naming conventions
for modules which don't offer complete CPython compatibility, while offer
subset or similar API.
It's no longer intended to provide just "raw" socket interface, may include
some convenience methods for compatibility with CPython socket - but anyway
just minimal set required to deal with socket client and servers, not wider
network functionality.