Are there any libraries which put a reliability layer on top of UDP broadcast? 

I need to broadcast large amounts of data to a large number of machines as quickly as possible, and generally it seems like such a problem must have already been solved many times over, but I wasn't able to find anything except for the Spread toolkit, which has a somewhat viral license (you have to mention it in all materials advertising the end product, which I'm not sure our customer will be willing to do).

I was already going to write such a thing myself (because it would be extremely fun to do!) but decided to ask first.

I looked also at UDT (http://udt.sourceforge.net) but it does not seem to provide a broadcast operation.

PS I'm looking at something as lightweight as a library - no infrastructure changes.


Question: Linux/CUPS printing example/tutorial?
Answer: CUPS doesn't have its own document description API. It doesn't need one: formats like PostScript, PDF, and JPEG are first-class citizens of CUPS. You use whatever program or API you like to create a such a file, and you then send it to CUPS (with lpr or with the CUPS API) and CUPS will transform it to the appropriate internal format and send it to the printer. 

So, for your case, you might use a vector graphics library like Cairo to author PostScript, and then you send that off to CUPS for printing. Here's a simple C example:

// compile with:
//   gcc -Wall -o cairo_print cairo_print.c `pkg-config --cflags --libs cairo` `cups-config --cflags --libs`

#include &lt;stdio.h&gt;
#include &lt;cairo.h&gt;
#include &lt;cairo-ps.h&gt;
#include &lt;cups/cups.h&gt;

// A4 width, height in points, from GhostView manual:
//   http://www.gnu.org/software/gv/manual/html_node/Paper-Keywords-and-paper-size-in-points.html
#define WIDTH  595  
#define HEIGHT 842  

int main(int argc, char** argv) {
  if (argc!= 2){
    fprintf (stderr, "usage: %s word\n", argv[0]);
    return 1;
  }

  // setup
  char* tmpfilename = tempnam(NULL,NULL);
  cairo_surface_t* surface = cairo_ps_surface_create(tmpfilename, 
                                                     WIDTH, 
                                                     HEIGHT);
  cairo_t *context = cairo_create(surface);

  // draw some text
  cairo_select_font_face(context, 
                         "Arial Black", 
                         CAIRO_FONT_SLANT_NORMAL, 
                         CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(context, 30);
  cairo_move_to(context, WIDTH/2, HEIGHT/2);
  cairo_show_text(context, argv[1]); // the text we got as a parameter

  // draw a dotted box
  const double pattern[] = {15.0, 10.0};
  cairo_set_dash(context, pattern, 2, 0);
  cairo_set_line_width(context, 5);
  cairo_rectangle(context, WIDTH*0.33, HEIGHT*0.33, WIDTH*0.5, WIDTH*0.5);
  cairo_stroke(context);

  // finish up
  cairo_show_page(context);
  cairo_destroy(context);
  cairo_surface_flush(surface);
  cairo_surface_destroy(surface);

  // print
  cupsPrintFile(cupsGetDefault(), tmpfilename, "cairo PS", 0, NULL);
  unlink(tmpfilename);

  return 0;
}


Strictly you don't need that temporary file: the CUPS API allows you to construct a stream and you can emit the page data into that (but a file is handy for debugging).