The Rand API is documented in a couple of papers that have been discussed here previously. I'll have to do a little googling to find them. The ChaosNET docs are the best MIT docs.
The API pretty much worked this way... there was one simple kernel hook. A small mod was done to the old nami routine (what modern UNIX calls 'lookup'), as a path was being parsed, the rest of the path was left in place made available to other routines.
Thus you could open: /dev/tcp/xxx and the string xxx was available in call that was implementing tcp and was then able to be passed xxx as a parameter. Hence, the traditional open/close/read/write was all that was needed.
Joy codified a new API that was supposed to be more network centric and map to different network protocols - the thinking being that open/close/read/write were insufficient semantics for network operations.
Also, the only other issue at the time was that BSD's select(2) did not exist, and the UNIX I/O were 100% synchronous. So some other mechanism (also discussed here) needed to be created to avoid blocking in the application. There were a couple of different schemes with V7's multiplexor call was created by Chesson for DataKit (which was similar to was used in the UofI code Arpanet code). Rand, UNET & Chaos had something else that gave the save async function, who's name I've forgotten at the moment, but I believe Noel posted the code for same in the last year from one of the MIT kernels - we had used it at CMU that we had gotten from Rand.