Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple wire protocol, what's a guy to do?

Tags:

c

linux

zeromq

ipc

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.

like image 346
brooks94 Avatar asked Sep 25 '12 15:09

brooks94


2 Answers

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.

like image 59
unwind Avatar answered Oct 16 '22 02:10

unwind


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

  • Protocol Buffers
  • MessagePack
  • JSON

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.

like image 39
Aaron Digulla Avatar answered Oct 16 '22 02:10

Aaron Digulla