In this chapter, we began to leverage and finally build from the foundation we've laid in previous chapters, opening up our applications to the full spectrum of network functionality available in C#. We learned that any application we write that we expect to be used by resources on our network must first be exposed to those resources through a port on our host machine. We looked at how ports are specified and registered, and learned about some restrictions that exist on how we can register our own, looking at the reason for, and the range, of well-known port addresses and the range of dynamic or ephemeral ports to which we cannot (or at least should not) register our applications.
Once we cemented that concept, we looked at the other side of the connection, and started working with sockets. We learned that sockets are a generic in-code representation of an active...