Search code examples
unixnetwork-programmingclient-serverpuredata

TCP/IP communication from the unix server to the Pure Data


I am interested in TCP/IP communication from the Unix server to the Pure Data. I have it realized using sockets on the Unix server side, and netclient on the Pure Data side. I exploited the chat-server tutorial for this (3.Networking > 10.chat_client.pd).

Now the problem lies that the server is streaming the data out as a "string" message delimited with ";"

My question is, is there a way to send something other than string message to Pure Data, like byte-stream or serialized number stream? Can Pure Data receive such messages?

Since string takes too many bytes to transfer, for example number "1024;" is already 5 bytes, while such an integer number is just 4 bytes.

UPDATE: For everyone that stumbles upon this post in search for the answer.

Apparently [netclient] on the Pure Data side cannot receive nothing else than ; delimited messages. So the solution for the problem posed above: My question is, is there a way to send something other than string message to Pure Data, like byte-stream or serialized number stream? Can Pure Data receive such messages?

The solution is to use [tcpclient], it can receive byte-stream data.

Now my question is, how do I get four compact numbers to work with? Now I have a series of bytes, at least in the correct order.

From my UNIX server I am sending a structure

typedef struct {
    int     var_code;
    int    sample_time;
    int     hr;
    float    hs;
} phy_data;

Sample data might be 2 1000000 51 2000.56

When received and printed in Pure Data I get output like this:

: 0 0 0 2 0 10 114 26 0 0 0 51 0 16 242 78

You can notice number 2 and number 51 clearly, I guess the others are correct as well.

How can I get these numbers back to a usable format? Maybe some manipulation with [bytes2any] and [route], but I haven't been able to extract the data with it?


Solution

  • here's an outline of what you have to do:

    • repackage the bytelist to small messages of the correct size for the various types.

      since all your elements are 4 byte long, you simply repackage your list (or bytestream, as TCP/IP doesn't guarantee to deliver your 16 bytes as a single list, but could also decide to break it into a list of arbitrary length) to a number of 4 atom lists.

      the most stable way, would probably be to 1st serialize the list (check the "serializer" example in the [list] help) and than reassamble that list to 4 elements.

      if you can use externals like zexy you could use [repack 4] for that.

      if you trust [netclient] to output your messages as complete lists, you could simply use a large [unpack ....] and 4 [pack]s

    • interpret the raw data for each sublist

      integers is rather simple, floats are way more complicated

    integers:

        |
        [unpack 0 0 0 0]
        |      |   |   |
        [<< 8] |   |   |
        |      |   |   |
        [+     ]   |   |
        |          |   |
        [<< 8]     |   |
        |          |   |
        [+         ]   |
        |              |
        [<< 8]         |
        |              |
        [+             ]
        |
    

    floats are left as an exercise to the user :-)