I need to write a program that will communicate with other .NET programs ... but also a legacy VFP program over TCP. I need to choose a fairly simple TCP message format that the VFP programmer can use. It could be as simple as a sequence of small XML blobs delimited by... I dunno, a null character? Whatever.

I need to choose between TcpListener/TcpClient and WCF. I started researching WCF but its architecture seems opaque and built-in Visual Studio templates are heavily biased toward making "web services" that act like a sort of RPC mechanism, but require a special "host" or web server that is external to the application. And Microsoft's [6-stage tutorial](http://msdn.microsoft.com/en-us/library/ms734712.aspx) makes WCF sound pretty cumbersome (involving code generators, command-line and XML crap just to remotely subtract or multiply two numbers).

I want a self-contained app (no "host"), I want control of the wire protocol, and **I want to understand how it works.** WCF doesn't seem to facilitate these things, so I abandoned it in factor of TcpListener/TcpClient.

However, the program is to serve as an intermediary between a single (VFP) server and many (.NET) clients, and there will be communication in both directions and across different connections. Using `TcpListener` and `TcpClient`, the work of juggling the connections and threads is getting a bit messy, I have no experience with `IAsyncResult`, and I'm not just not confident in my code quality.

So I would like to solicit opinions again: should I still consider WCF instead? If yes, can you point me toward answers to the following questions?

1. Where in the web is a good explanation of WCF's architecture? Or do I need a book?
2. How is bi-directional communication done in WCF, where either side (of a single TCP connection) can send a message at any time?
3. How can I get past all the web-services and RPC mumbo-jumbo, and control the wire protocol?
4. In WCF, how do I shut down the app cleanly, closing all connections in parallel without hacky Thread.Abort() commands?

If no, how can I set up my code (that uses TcpListener/TcpClient/NetworkStream) so that I can read a message from a NetworkStream, but also accept requests from other connections, shut down cleanly at any time, and avoid wasting CPU time to poll queues and NetworkStreams that are inactive?