Apparent race condition in udpsend w/ host message

Jesse Morris's icon

Hi!

I've got a number of similar OSC devices I want to talk to, all at different IP addresses.

The number of devices and what each of them does is somewhat variable, so I want one patcher to be able take a list and use the first element as the address to send to. I've done it something like this:

Max Patch
Copy patch and select New From Clipboard in Max.

If I don't send stuff back to back (like the button in this example) then everything works fine. But in this example, about 1 time in 10, it sends messages to the wrong address. If I add a thing that waits a bit between messages (like IDK uzi 50 into a counter) then it works reliably again.

Since it's got an attribute to control it, udpsend clearly has a queue size. My theory is that udpsend doesn't remember what the host (or presumably port) was when a message was queued up, and changing the host (or presumably port) changes it for every message still in the queue. Given that there is no guarantee of how long it takes a message to leave udpsend's queue, this makes the host message basically useless for anything but static configuration.

I personally feel this is a surprising behavior and a bug, and udpsend should honor max's normal timing paradigm where the host message only affects stuff that udpsend receives after the host message. That means I feel that udpsend should keep the host and port in the queue alongside the payload. However if this is "works as intended" I would be interested if anyone has any alternate solutions, that don't involve making a separate udpsend for every gizmo I happen to plug in to my network.

Source Audio's icon

This is not prefered way of queueing messages.
You should form it into single message, like:
host 192.168.123.12, port 7777, hello

If You don't send very large messages,
better way would be broadcasting from
the UDP master, and changing only ports.
Example:
udpsend 255.255.255.255 5555
message :
port 6666, hello would be received
on all UDP clients listening to port 6666.
In a large network with more than 200
UDP clients, that showed as best way of
communication.
Or make several udpsend objects, all broadcasting
but on dedicated ports for each client.
Master gets fixed IP and port for reporting back
Messages from clients get short ID prepended.
-----------
max packet size for broadcasting is 1460 bytes.

Jesse Morris's icon

I appreciate the code style input (I'm by no means a whiz with max yet), but I've verified with print watchpoints that my code is delivering stuff to the udpsend in the right order (host, payload, host, payload), so I don't think using messages and commas will accomplish much (and it's not really available to me - this was a simplified version of things - in reality my hosts are coming out of a dict). And it's with a packet sniffer that I've verified that the host commands are not being properly honored 100% of the time. I still think this is a bug in udpsend.

HOWEVER, thanks to your suggestion of using broadcast UDP, I am no longer affected by this issue. That solves my problem nicely. I'd tried it a year ago, but my network topology was still up in the air, and I didn't trust broadcast to get everywhere - now it is nailed down and works with broadcast, but I just hadn't reconsidered it. This also fixes another problem I was going to have to make a clunky hacky solution to, so an extra thanks for that.

I strongly suspect that if I were changing ports the same way I'm currently changing hosts (as you suggest), I'd see the same kind of problem except sending to the wrong port instead of to the wrong address, but I can just send everything to 192.168.123.255 7474 and let the clients ignore packets based on the OSC address .

Source Audio's icon

Glad that You found the solution.
I had a lot of problems in that mentioned project with many clients involved.
Broadcasting came to the rescue for the part of master talking to clients.
But I also had to control the traffic in a way that each client got an ID
assigned which I used to address clients to send data to master, all in controlled
and timed queue.
10 ms per step was enough to prevent any loss, and packets were up to
2000 chars of text, on a wired gigabit network.