MUSCLE: Crossbar Server, Portable Messaging and Support Classes

4/25/2018 v6.82 jaf@meyersound.com

Jeremy Friesner / Meyer Sound Laboratories Inc.

Win32 compatibility contributions by Vitaliy Mikitchenko

C# client code by Wilson Yeung

SSL support code contributed by Nathan Whitehorn

Note: To compile the server, cd to the "server" subdirectory and type 'make'. The server executable, "muscled", should be generated. You can run this server from the command line, (type "muscled help" to get info about some options) and connect to it with any MUSCLE-aware program.

Alternatively, if you prefer a server that runs as a GUI program and you have Qt installed, you can cd to the "qtsupport/qt_muscled" subdirectory and type "qmake; make". A GUI server program named qt_muscled will be created.

The main goal of these classes is to provide an easy way to use BMessage-style message passing across a network of heterogeneous (MacOS/X, Linux, Windows, BSD, Unix, etc) systems. The secondary goal is just to provide some handy data containers and other utility classes.

All of this code (except the atheossupport, besupport, and qtsupport directories) should compile under any up-to-date C++ compiler-- no proprietary APIs are used except inside of the appropriate #ifdefs.

For better documentation than this, please see the MUSCLE web site.

This code has been compiled (typically with gmake, or MSVC in Windows) and tested in the following environments:

  1. SUSE, Debian, and Ubuntu Linux on various 32-bit and 64-bit PCs
  2. MacOS/X on various PowerPC and Intel based Macs
  3. Microsoft Windows XP and Windows 7 using Visual Studio 2008 or higher (use the projects files in the 'vc++' subfolder)

It has no known bugs, but may have some yet-to-be-discovered ones. Use at your own risk, Meyer Sound is not responsible for any disasters, blah blah blah.

Directory contents descriptions follow:

    csharp/

    This directory contains Wilson Yeung's alpha port of the Muscle client API to the C# language. Email Wilson (wilson@whack.org) with questions about this port.

  1. dataio/

    This directory contains the DataIO interface class, which is an abstraction for any file-like device that can read or write sequences of bytes, and (optionally) seek to a specified position. The DataIO class defines an interface for devices that you can Read() bytes from or Write() bytes to. This folder also includes some useful implementations of the DataIO interface, including the following:

    AsyncDataIOWrapper that delegates I/O calls to an internal I/O thread
    ByteBufferDataIOFor file-style reading/writing to a ByteBuffer held in memory
    ChildProcessDataIOFor launching a child process and communicating with it via its stdout/stdin
    FailoverDataIO.Wrapper for automatic fallback to a second output when a primary output fails
    FileDataIOFor reading/writing via a C (FILE *) file handle
    FileDescriptorDataIOFor reading/writing via a Unix file descriptor
    MultiDataIOMultiplexer wrapper class for writing to multiple outputs at once
    NullDataIODummy class for directing data to the bit-bucket
    PacketizedDataIOWrapper for making TCP act more tr UDP
    RS232DataIOFor communicating via an RS-232 serial port
    SSLSocketDataIOFor communicating over SSL over TCP
    StdinDataIOFor reading from stdin
    TCPSocketDataIOFor communicating using a TCP socket
    UDPSocketDataIOFor communicating using a UDP socket
    XorDataIOWrapper class that applies XOR-"encryption" to all data that flows through it

  2. delphi/

    This directory contains the MUSCLE client API written for the Delphi programming environment. The contents of this directory were contributed by Matthew Emson; see the Readme.txt file in this directory for more information.

  3. html/

    This directory contains various HTML documentation for the MUSCLE project, including the Beginner's Guide to MUSCLE, a document on how to create custom MUSCLE servers, and the autodoc folder that contains files useful for creating API documentation using the DOxygen documentation tool.

  4. iogateway/

    This directory contains the AbstractMessageIOGateway interface. An AbstractMessageIOGatweay is a "gateway" object that knows how to manage bidirectional FIFO Message-stream traffic going to and coming from a DataIO object. A gateway object queues outgoing MessageRefs, and when there is room in the outgoing buffer to send one, it flattens the next MessageRef in the outgoing-message-queue into a sequence of bytes, and sends those bytes out via the DataIO object. It also reads bytes coming in from the DataIO object and assembles those bytes back into Message objects, which are then handed back to the AbstractGatewayMessageReceiver specified by the calling code. This directory also contains some useful implementations of the AbstractMessageIOGateway interfaces, which are as follows:

    MessageIOGatewayFlattens Messages to the standard MUSCLE flattened-message binary format
    PacketTunnelIOGatewayFlattens Messages into a series of fixed-size packets suitable for UDP transmission
    PlainTextMessageIOGatewayConverts free-form lines of ASCII text into Messages, and vice versa
    RawDataMessageIOGatewayConverts arbitrary raw data into Messages, and vice versa
    SLIPFramedDataMessageIOGatewaySimilar to the RawDataMessageIOGateway class, except it uses SLIP framing conventions
    SignalMessageIOGatewayDummy gateway that doesn't send actual data, only indicates when data is available

  5. java/

    This directory contains a Java implementation of the MUSCLE client side API. You can use the code in this folder to enable your Java program to talk to a MUSCLE server or any other program that speaks the MUSCLE Message protocol.

  6. message/

    This directory contains MUSCLE's Message class. A Message is a general-purpose data structure that is similar to BeOS's BMessage class. A Message consists of a 32-bit integer "what code", plus zero or more named data fields, each of which can contain one or more data items of a specified type.

    Here are some relevant details:

    1. MUSCLE messages support the following field types:

      int8B_INT8_TYPE8-bit signed integer values
      int16B_INT16_TYPE16-bit signed integer values
      int32B_INT32_TYPE32-bit signed integer values
      int64B_INT64_TYPE64-bit signed integer values
      boolB_BOOL_TYPEboolean values
      floatB_FLOAT_TYPEIEEE 754 floating point values
      PointerB_POINTER_TYPEPointer values (non-flattenable)
      MessageB_MESSAGE_TYPEMessage objects
      Flattenable(various types)Flattened Flattenable objects
      StringB_STRING_TYPEUTF8 character strings
      RectB_RECT_TYPERectangles (floats for left,top,right,bottom)
      PointB_POINT_TYPEPoints (floats for x,y)
      Raw Data BufferB_RAW_TYPESequences of zero or more untyped bytes
      TagB_TAG_TYPEUser-provided arbitrary objects (non-flattenable)

    2. Message is a subclass of Flattenable (see below), and therefore a Message can be serialized into a "flattened" buffer-of-bytes, which can be sent across a network or saved to a file, and later the bytes can be unflattened back into an equivalent Message object. This is the basis for most MUSCLE network communication. The flattening and unflattening is endian-aware, so that e.g. a PowerPC machine can communicate with an Intel machine without problems.
    3. Message has a GetFieldNameIterator() method, which returns a MessageFieldNameIterator object, which can be used to iterate over the fields of a Message.
  7. minimessage/

    This directory contains the MiniMessage and MiniMessageGateway C APIs. These APIs are C implementations of the C++ Message and MessageIOGateway classes. They can be used in cases where (for whatever reason) you want to code your program in C only and avoid C++. They aren't as easy-to-use as the C++ implementation, but they should be sufficient for simple things, and they compile down to only a few dozen kilobytes of object code. See the testmini.c and minireflectclient.c test files in the tests directory for examples on how they are used.

  8. micromessage/

    This directory contains the MicroMessage and MicroMessageGateway C APIs. These APIs are C implementations of the C++ Message and MessageIOGateway classes. These APIs go even farther towards minimalism than the minimessage APIs: in particular, these APIs never allocate or free any data. Instead of converting the message's flattened-data-bytes into a separate in-memory data structure like Message and MiniMessage do, MicroMessage operates on the flattened-data-bytes directly. This makes for a potentially much more efficient implementation; the main downside is that when creating a MicroMessage, you can only append data; you cannot insert or remove fields that you previously added.

  9. python/

    This directory contains a minimal MUSCLE client-side API written in Python. You can use the code in this directory to enable your Python scripts to talk to a MUSCLE server or any other program that speaks the MUSCLE Message protocol. Also included in this directory is some C++ glue code (in PythonUtilityFunctions.cpp) that is useful when embedding Python code into C++ code -- the glue code uses MUSCLE Messages as to transfer arguments from C++ to Python context and back again.

  10. qtsupport/

    This directory contains several classes that support clients that use TrollTech's Qt cross-platform GUI API. The main one is the QMessageTransceiverThread class, which is a Qt-aware subclass of the MessageTransceiverThread class. Using a QMessageTransceiverThread for your network I/O makes network communication very simple; instead of dealing with bytes and network protocols, you simply receive a Qt signal whenever incoming Messages are available, and call a method to send a Message, etc. This folder also contains some sub-directories that contain small example programs written for MUSCLE+Qt:

    qt_exampleA simple multi-user 'game' and chat program
    qt_advanced_exampleA demonstration of embedding a MUSCLE server thread inside a Qt application
    qt_muscledA demonstration of a Qt app that runs a MUSCLE server as a child process
    qt_muscled_browserA hierarchical browser GUI for seeing what data is present in a muscle server's database

  11. reflector/

    This directory contains server code for an n-way "message crossbar server" program. This program will listen on a specified port for TCP connections, and will allow the TCP connections to "talk to each other" by forwarding Messages from one client to another (or to multiple others). The ServerProcessLoop() method implements the server's event loop, while the AbstractReflectSession class is the interface for the server's side of a TCP connection. There are currently two subclasses of AbstractReflectSession included: the DumbReflectSession class just reflects all received Messages to all connected clients, while the StorageReflectSession class adds nice features like wildcard-based Message routing, server-side data storage, and "notify-me-on-change" subscription services. (See the MUSCLE Beginner's Guide for more info on this) More elaborate logic can be added by creating subclasses of these classes.

  12. regex/

    This directory contains code to support the use of regular expressions. This includes some C++ pattern-matching utility classes, as well as a sub-folder containing Henry Spencer's freeware C regex engine, for use in OS's that do not provide their own regex library.

    Classes implemented in this directory include:

    FilePathExpanderExpands shell-style wildcards into a list of file paths
    PathMatcherControls wildcard-directed recursive iterations down the tree of DataNode objects
    QueryFilterImplements various predicate-logic operations on DataNode Message data
    StringMatcherDoes shell-style pattern matching on arbitrary character strings
    SegmentedStringMatcherLike StringMatcher, except that the strings are divided up into substrings which are evaluated separately (e.g. "a*/b*")

  13. sdlsupport/

    This directory contains the SDLMessageTransceiverThread class, which is a handy way to implement MUSCLE communication ability into your SDL program. SDLMessageTransceiverThread class is just a thin wrapper subclass around the MessageTransceiverThread class, but it interfaces MessageTransceiverThread to SDL's event-notification system.

  14. server/

    This contains the Makefile and main entry point for the "muscled" server executable, and the "admin" muscled-server-administration utility.

  15. support/

    This directory contains various "small things" needed to compile the rest of the code. These include byte-ordering macros, BeOS-style type codes, typedefs, and result constants, and the Flattenable interface definition.

  16. syslog/

    This directory contains functions for logging event messages to stdout and/or to a file. Log messages can be "raw" (works just like printf) or nicely formatted with the current time, redirected to a file, and so on. The logging system also has optional functionality to rotate, compress and/or delete old log files, to avoid filling up too much disk space.

  17. system/

    This directory contains classes that represent "generic" interfaces to OS-specific APIs; as such, they are not guaranteed to work on every platform. Currently this directory contains the following classes:

    AcceptSocketsThreadA thread that accepts incoming TCP connections and hands them back to the parent thread
    AtomicCounterAtomic-increment and atomic-decrement counter, for lock-free reference-counting
    DetectNetworkConfigChangesSessionA session object that notifies the program when the host computer's network configuration has changed
    GlobalMemoryAllocatorCode to monitor and optionally restrict the program's heap usage
    MessageTransceiverThreadRuns a MUSCLE ReflectServer object in a separate thread. Provides asynchronous I/O
    MutexProvides efficient in-process locking (aka critical sections) for thread-safety
    SetupSystemProvides standardized startup and shutdown routines that must be used by any MUSCLE process
    SharedMemoryImplements inter-process shared memory regions, including inter-process read/write locking ability
    SignalMultiplexerMakes system signalling (e.g. catching of SIGINT or SIHUP) available to multiple pieces of code in the same process
    SystemInfoProvides information about the environment the program is operating in (current directory, OS version, etc)
    ThreadAn OS-neutral Thread class for multithreading purposes. Includes send/receive Message functionality for easy control
    ThreadLocalStorageAn OS-neutral implementation of thread-local data storage
    ThreadPoolA thread pool implementation to allow handling of many Messages in parallel across a finite number of threads.

  18. test/

    This directory contains various test programs that I use to test and develop the code, and a Makefile to build them with.

    Currently this directory contains the following programs:

    bandwidthtesterGenerates lots of Message traffic and measures how fast a MUSCLE server can receive it
    calctypecodePrints out the decimal equivalent of a four-character ASCII what-code
    printtypecodePrints out the four-character ASCII equivalent of a given decimal value
    chatclientMinimalist BeShare-compatible chat client that can connect to any MUSCLE server
    deadlockDeliberately tries to create a deadlock. Primarily used for testing deadlockfinder.
    deadlockfinderParses the output generated by MUSCLE's MUSCLE_ENABLE_DEADLOCK_FINDER feature, and detects potential deadlock issues
    findsourcelocationsParses source code and lists source-locations matching a specified code generated by MUSCLE's MUSCLE_INCLUDE_SOURCE_CODE_LOCATION_IN_LOGTIME feature
    hextermA simple interactive terminal that sends, receives, and prints hexadecimal representation of all bytes received via TCP, UDP, etc.
    portableplaintextclientA simple interactive terminal for ASCII communication over TCP
    portablereflectclientA simple interactive terminal for Message communication over TCP (typically with a MUSCLE server)
    portscanAttempts to connect via TCP to a range of ports on a host, and reports which ports accepted the connection
    printsourcelocationsPrints the source-code-location codes of all LogTime() commands. Useful for building up a directory of source-location-codes for a given codebase
    readmessageReads a flattened Message from a file on disk and prints it to stdout in human-readable form
    serialproxyMakes a local serial port available to the network over TCP
    svncopyCreates a command script for bulk-adding specified files to an SVN repository
    testatheossupportTests the AtheOS support files in the atheossupport folder
    testbatchguardUnit test for the BatchGuard class
    testbesupportTests the BeOS support files in the beossupport folder
    testbytebufferUnit test for the ByteBuffer class
    testchildprocessUnit test for the ChildProcessDataIO class
    testendianUnit test for the endian-swapping routines
    testfilepathinfoUnit test for the FilePathInfo class
    testgatewayUnit test for the MessageIOGateway class
    testhashtableUnit test for the Hashtable class
    testmatchfilesUnit test for the ExpandFilePathWildCards() function
    testmessageUnit test for the Message class
    testmicroUnit test for the MicroMessage and MicroMessageGateway C routines
    testminiUnit test for the MiniMessage and MiniMessageGateway C routines
    testnagleUnit test to verify the presence of absence of Nagle's algorithm
    testnetconfigdetectUnit test for the DetectNetworkConfigChangesSession class
    testnetutilUnit test for the GetNetworkInterfaces() function
    testpacketioUnit test for the PacketizedDataIO clas
    testpackettunnelUnit test for the PacketTunnelIOGateway class
    testparsefileUnit test for the ParseFile() and ParseArgs() functions
    testpoolUnit test for the ObjectPool class
    testpulsenodeUnit test for the PulseNode class
    testqueryfilterUnit test for the QueryFilter classes
    testqueueUnit test for the Queue class
    testrefcountUnit test for the RefCount class
    testreflectclientUnit test for the various OS-specific MessageTransceiverThread subclasses
    testregexUnit test for the StringMatcher class
    testresponseTest to measure the response latency of a muscle server
    testserialUnit test for the RS232DataIO class
    testsharedmemUnit test for the SharedMemory class
    testsocketmultiplexerUnit test for the SocketMultiplexer class
    teststringUnit test for the String class
    testsysteminfoUnit test for the SystemInfo functionality
    testthreadUnit test for the Thread class
    testthreadpoolUnit test for the ThreadPool class
    testtimeUnit test for the various time-string-parsing and time-string-generation functions
    testtupleUnit test for the Tuple class
    testtypedefsUnit test for MUSCLE's standard type typedefs (int32, int64, etc)
    testudpTest/demonstration of using MUSCLE to send/receive UDP packets
    testzipUnit test of the ReadZipFile() and WriteZipFile() functions
    udpproxyForwards UDP packets from one computer to another, and vice versa
    uploadstressSpams a MUSCLE server with requests to see if the server can keep up
    win32clientExample of integrating MUSCLE client code with a Win32 event loop

  19. util/

    This directory contains many useful one-off classes and function collections, including:

    1. BatchOperator

      BatchOperator is a templated mechanism for ensuring that a specified method gets called on the first-level recursion into a call tree, and that a matching method gets called on the final recursion out of the call tree. This is handy for making sure that setup and shutdown code is called a the correct times.

      ByteBuffer

      ByteBuffer is an intelligent byte-array class, that stores its length, knows how to resize itself efficiently, is reference-countable and flattenable, etc.

    2. CountedObject

      CountedObject is a class that other classes can be derived from if you want to keep track of how many instances of them are in memory at any given time.

    3. CPULoadMeter

      CPULoadMeter reports the percentage of CPU time being used on the local computer from moment to moment (similar to what is reported in Task Manager under Windows, or Activity Monitor under MacOS/X)

    4. Directory

      Directory is a platform-neutral API for scanning a filesystem directory and iterating over its contents.

    5. DebugTimer

      DebugTimer is a useful utility class that is useful for debugging performance problems. It records the current time in its constructor, and then in its destructor it prints out the time that has elapsed since then (if the elapsed time is more than a specified minimum time).

    6. FilePathInfo

      FilePathInfo is a platform-neutral API for querying the various properties of an entry at a specified location in a file system (e.g. is a file, a directory, or a symlink, how large is it, when was it created or modified, etc)

    7. Hashtable

      Hashtable is a handy hash table class, with templated key and value types and the traditional O(1) lookup time. In addition to that, it includes other nice features, such as "safe" iterators (so you can modify the Hashtable while iterating through it), minimal-frequency memory allocations, and the ability to sort the table by key or by value (it maintains the ordering of the objects placed into the table). Hashtable is used by the Message class, but is also quite useful on its own.

    8. IPAddress

      IPAddress is a class that represents an IPv4 or IPv6 address in a standardized manner. There is also an IPAddressAndPort class which represents the combination of an IP address and a port number.

    9. NestCount

      NestCount is a simple class for recording when the execution path enters or exits a particular function, and (optionally) making decisions based on whether a specified function is currently on the stack or not.

    10. NetworkUtilityFunctions

      NetworkUtilityFunctions.cpp is a repository of user-friendly wrapper functions around common BSD socket operations, such as setting up sockets to connect or accept TCP connections, or binding a UDP socket to a port.

    11. ObjectPool

      The ObjectPool class is used to avoid excessive deletions and allocations of commonly used objects (such as Messages or RefCountMems). It works by recycling the items for re-use, and is templated so it can be used for any type of object.

    12. PulseNode

      The PulseNode is an interface for objects that want to execute a particular action at a specified time. It works in conjunction with the standard MUSCLE event loop. Implementing classes define a Pulse() method that will be executed at a specified time, and a GetPulseTime() method that returns a clock value indicating when Pulse() should next be executed.

    13. Queue

      The Queue class is just a little templatized double-ended queue (i.e. AddHead(), AddTail(), RemoveHead(), and RemoveTail() are O(1) operations). It can be used as a Vector, Stack, or FIFO. It's templatized for easy, type-safe reuse.

    14. RefCount

      The RefCount class implements generic reference counting for C++ objects or arrays. To enable reference counting on an object, you simply create a single Ref for that object, and (optionally) make one or more copies of the Ref via the copy constructor or the equals operator. Then, when the last Ref object disappears, the C++ object or array is automatically deleted. It's not a garbage collector, but it beats having to keep track of all your allocations by hand...

    15. Socket

      A reference-countable C++ class wrapper for a socket or file descriptor. Wrapping sockets and file descriptors in these objects allows them to be easily shared across objects without introducing the possibility of leaking them, or closing them before some other piece of code is done using them.

    16. SocketMultiplexer

      An easy-to-use wrapper around the select() socket-multiplexing API. It's also possible to use this as a wrapper around various select() alternatives, such as poll(), epoll(), or kqueue(), by recompiling the code with the appropriate compiler flags (e.g. -DMUSCLE_USE_POLL)

    17. String

      The String class is just your basic character-string class, in this case inspired by the java.lang.String class from Java. This class was originally written by Michael Olivero (mike95@mike95.com) and modified by myself. String extends Flattenable, so it can be serialized in a generic manner.

    18. StringTokenizer

      A string tokenizing class similar to Java's Java.util.StringTokenizer, only more efficient.

    19. TimeUtilityFunctions

      TimeUtilityFunctions.h is a repository of functions for dealing with microsecond-accurate timing issues.

  20. vc++/

    This directory contains project files for building muscled under Visual C++ for Windows. These files were provided by Vitaliy Mikitchenko (aka VitViper)

  21. winsupport/

    This directory contains the Win32MessageTransceiverThread class, which is useful for interface MUSCLE code to the standard Win32 GUI event loop. You can use this class to enable your Win32 C and C++ programs to communicate with a MUSCLE server or any other program that speaks the MUSCLE Message protocol.

  22. zlib/

    This directory contains a subfolder named zlib (which contains the complete source code of the zlib compressor/decompressor package). This directory also contains some zlib-related muscle source, including ZLibCodec, which is a convenience class for compressing and decompressing chunks of data, ZLibDataIO, a wrapper class for transparent compression and decompression of I/O streams, and ZLibUtilityFunctions, which contain some convenience functions for quickly compressing and decompressing a Message in a compatible manner.

For more details, have a look at the autodocs, header files and/or the source itself.

-Jeremy