What are the pros and cons of the different IPC methods?

Named (or anonymous) Pipes

Use file APIs, so relatively simple to implement if you're at all file-savvy. Not queued. Connection-oriented, i.e. point to point, and therefore can't broadcast. Can operate across session boundaries, but need attention to security issues.

Mailslots

Queued, connectionless and can therefore broadcast. Simple to use, but have some drawbacks:

  1. Because the sender doesn't know what protocols are installed on the receiver, mailslot messages are duplicated on every installed protocol, and it's your responsibility to sort out the resulting mess (usually with some sort of tagging system).
  2. A length limit of around 400 bytes or so.
  3. Don't have guaranteed delivery, though I've yet to see one fail to arrive (on a LAN : see point 4).
  4. Broadcasting to a group (e.g. a domain) works fine... until you want to do it outwards over a RAS link. Then it just plain breaks. This fact bit both me and Intel at the time. Microsoft explained this blocking behaviour to me as their desire not to flood another network with broadcast UDP, which is fair enough... if they'd actually got it right. In actuality, about one message in 6 got through (enough with the war stories - Ed.).

WM_COPYDATA

Very simple to use. Obviously message based, so you have to pump messages (an issue for console apps and services). If you need something quick and dirty for occasional-use messaging, both apps - or at a minimum the receiver app - have a message pump and you can get a window handle, this is hard to beat.

Memory Mapped files

MMFs don't necessarily need to be associated with a disk file, so you can use them for IPC. Since MMFs are the underlying implementation technique for most of the other IPC methods, you won't get much better performance if a shared memory technique fits your requirement.

DLL Shared Sections

These require you to write a DLL of course, which seems like overkill just to get two processes talking. There is also a technical problem which can arise because Windows recognises DLLs by their path, not their name. So two copies of the same DLL from different paths can get loaded, and the loading processes won't see the same section. Bummer.

Another more serious problem arises because of changes to Windows made around the time of Windows 2000. Because of the rise in importance of virtualisation in general and terminal server in particular, sharing data across session boundaries was thought to be a security risk. Hence MS deliberately broke the operation of shared sections across sessions. Each session gets its own copy of the data, shared only within that session. This means that on Vista and Windows 7, with their service hardening feature that puts the services into their own session and the console in a different one, you can't share data between apps and services using a shared section. Fortunately Memory Mapped Files still work across sessions, so you can always use one of those. I recently converted a complex shared section DLL to use multiple MMFs and the job took just over a day, so... pretty easy. The downside is that if you're using MMFs for cross-session comms, the MMF itself has to be created by a high privilege process. I used a service to do this.

DDE / NetDDE / ddeml

Message based shared-memory technique. Functional, but supposedly moribund. I can only assume MS doesn't want us to use it because either (a) it doesn't consume enough processor cycles to keep Intel happy, or (b) it works. Can cause problems because of the broadcast initiate sent via SendMessage. SendMessage is synchronous and the broadcast goes to every window in the system, so if someone out there has a window but isn't pumping messages, your call to SendMessage won't ever return (Win32 uses GetMessage, PeekMessage and WaitMessage as synchronisation points, so despite the fact that SendMessage is supposed to be a direct call to your WndProc, it won't get actioned). The cure is to use the SendMessageTimeout API.

Sockets

Microsoft's Winsock support is based upon the Berkeley Unix sockets implementation, with proprietary (naturally, this is Microsoft) extensions. Those extensions include support for asynchronous socket calls. Sockets have the advantage of simplicity and portability for heterogeneous environments. If you are working with Internet-aware applications, sockets are your IPC of choice.

There are two types of sockets, stream (TCP) and datagram (UDP). TCP is point to point and offers guaranteed in-order delivery. UDP supports broadcast, is size-limited and offers none of the above. Note that stream sockets by their very nature do not support framing: one of your messages may be split across two or more packets, so your protocol must take account of this (i.e. one receive notification != one whole message).

Under Windows, there are various implementation techniques available to you.

Implementations
Synchronous Sockets Basically, using worker threads and blocking socket calls. This is simple to implement, but doesn't scale at all well.
Asynchronous: Overlapped I/O Finicky to code, and doesn't really offer any advantage over the next two methods.
Asynchronous: Message-based Using the function WSAAsyncSelect, you specify that you want to receive notifications of socket events via the windows message queue. Upon receipt of the event, calling a specified function resets the notification ready for the next event. If you have a GUI app and maximal throughput isn't a necessity, this is a good bet.
Asynchronous: I/O Completion Ports In this technique events are queued through an I/O completion port, so it combines the convenient queueing of the WSAAsyncSelect method with the performance of overlapped I/O. For non-GUI apps, or those that require extreme throughput, this is a good bet. Quality sample code is also available from www.mvps.org !

Note - Winsock 2.0 supports socket communications over protocols other than TCP/IP.