7

I have a simple server written in C. It's main purpose is to communicate with some business partners over a proprietary protocol. For that reason and a few others, it must be written in C. I have a number of other processes, however, written in other languages (e.g. Python) that must communicate with the server (locally, on the same Linux server).

What are the best options for cross-language IPC in this scenario? Specifically, I think I have a handle on transport technologies: Unix domain sockets, named pipes, shared memory, ZeroMQ (Crossroads). I'm more interested in the best way to implement the protocol, in order to keep the C code small and maintainable, while still allowing communication from other languages.

Edit: there seems to be some confusion. I'm not interested in discussion of pros/cons of domain sockets, shared memory et. al. I am interested in msgpack (thanks unwind), and other technologies/approaches for implementing the wire protocol.

Jakob Möllås
  • 4,239
  • 3
  • 33
  • 61
brooks94
  • 3,836
  • 4
  • 30
  • 57
  • Wild guess, sockets if you want to transfer data serially, shared memory+shared semaphore if you want faster and more random ipc. – Shahbaz Sep 25 '12 at 15:18
  • OK, so what languages do you need, and what is required from the protocol? If it's just C & Python on Linux, you can trivially use fixed-size structures and be done with it. – Useless Sep 25 '12 at 15:35
  • Go is actually the primary other one, haskell is a nice to have. – brooks94 Sep 25 '12 at 15:57

2 Answers2

4

It's hard to optimize (=select the "best") when the requirements are unknown. You do state that your goal is to keep the C code "small and maintainable", which seems to imply that you should look for a library. Perhaps msgpack over a local socket?

Also, your basic premise that the server must be written in C because you have a proprietary protocol seems ... weird, at least.

unwind
  • 391,730
  • 64
  • 469
  • 606
4

Edit: What you need is a "serialization framework", i.e. something can turn a memory structure into a byte stream. The best candidates are:

Pros/cons:

Protocol Buffers

  • + Fast
  • + Easy to version (which you'll start to love very much when you need to make a change to your message format for the first time and which you will curse to hell before that)
  • - Solves many problems which you don't know about, yet. That makes the API a bit "strange". I assure you, there are very good reasons for what and how they do it but you will feel confused sometimes.

I don't know much about MessagePack.

Lastly:

JSON

  • + Any language out there can read and write JSON data.
  • + Human readable without tools
  • - somewhat slow
  • - the format is very flexible but if you need to make big changes, you need to find a strategy to figure out what format (= which fields) a message has when you read it.

As for the transport layer:

Pros/cons:

Shared memory

  • + Fastest option
  • - You need a second channel (like a semaphore) to tell the other process that the data is now ready
  • - gets really ugly when you try to connect more then two processes
  • - OS specific

Named pipes

  • + Very easy to set up
  • + Fairly fast
  • - Only allows two processes to talk ... or rather one process to talk to another in a single direction. If you need bi-directional communication, you need several pipes

Sockets

  • + Pretty easy to set up
  • + Available for all and any languages
  • + Allows remote access (not all processes need to be on the same machine)
  • + Two-way communication with one server and several processes
  • - Slower than shmem and pipes

ZeroMQ

  • + Like sockets but better
  • + Modern API (not that old IPC/socket junk)
  • + Support for many languages...
  • - ...but not all

If you can I'd suggest to try ZeroMQ because it's a modern framework that solves many of the problems that you'll encounter with the older technologies.

If that fails, I'd try sockets next. They are easy, well supported and docile.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • Sorry, was hidden too well under things that you're not interested in :-) – Aaron Digulla Sep 25 '12 at 17:02
  • 3
    I'm using ZeroMQ and Protocol Buffers for similar purposes. They are working great, makes prototyping a lot faster compared to low level sockets and manual byte parsing. I couldn't be happier with ProtoBuf. ZeroMQ is also great but it has some weird quirks. – japreiss Sep 25 '12 at 17:13
  • +1 for the pb and zmq combo. I use it all over the place with code that interfaces between c++ and python. – g19fanatic Dec 05 '12 at 21:46