It's hard to do justice to the topic of "networking" in a single post. It's a large field, and like you said, there are lots of complexities that come up with it. The devil is in the details.
You might consider using lidgren. It's rather popular. I think it actually ships with MonoGame. To be honest, though, I looked into it when I was doing my networking stuff in my last game in November. It didn't take me too long before I decided I'd have more control over things if I built my own networking library, so that's what I went with. It worked pretty well, doing it myself, but I also didn't address dropped packets or latency. So I kind of cheated by not doing the hard parts.
(My networking library was simply based on the .NET Framework's TcpClient class, and as PiscesMike mentioned, I just serialized everything to a byte array and pumped it into a stream object. I initially used the built-in serialization mechanism, but later wrote my own serializer because I could get it down to about 10% of the size.)
You'll be doing far better than not if you can find a way to simulate lost packets, slow delivery of packets, out of order delivery of packets, and connection losses. You don't want to have to go hunt down a "real" network with those problems to test it out. Simulation is the way to go. So if you build your own, make sure you account for a way to do that. (Lidgren has simulation built in.)
I know that's not much of a full answer, but perhaps it gives you some things to think about.