OSCReceiver Port Reuse

Hi Guys,

I am trying to set up an OSC server with multiple clients, each client connecting to a different server port (in order to differentiate messages from different clients). My OSC server creates an OSCReceiver for each requested client connection and tries to connect it to a spare port. The idea is to iterate a range of port numbers until it gets to one that it can connect/bind to.

Unfortunately, it seems that two or more OSCReceivers can connect to the same port number. I can see that port reuse is enabled by default for DatagramSocket and is not disabled in the OSCReceiver class. I am not very knowledgeable on sockets so was wondering if there is a valid use case for OSCReceiver being able to reuse ports or could port reuse be disabled?

On a side note, I would love to transmit OSC messages/bundles over TCP, WebSockets, etc but the OSCMessage/OSCBundle classes do not provide a way of reading/writing the raw data. Is this something that could be supported in a future release?

Many thanks,

Chris

Do you really need to use multiple ports? I suspect you could get quite far using a single port and multiple listeners to different addresses. I’ve not done any OSC stuff myself, however, so I could be missing something significant.

We’ve had other requests to support different communication protocols so doing this is in our backlog. However, we also have a lot of more important stuff we’d like to finish first, so there’s going to be no movement on this anytime soon.

Hi Tom,

Thanks for your response, I have tried various approaches to this. A common issue I have encountered is synchronising a slider on multiple clients. The problem is trying to get the server to forward slider change messages to other clients without looping it back to the sender (as the transport delay causes the slider to jump around all over the place).

Using basic addressing alone “/slider1”, there is no way to know where the value originated from. The OSC Receiver doesn’t provide any details about the sender, only the OSCMessage itself.

The OSC address could be “/clientID/slider1”

/client1/slider1
/client2/slider1
…

The problem with this is that the OSCReceiver::ListenerWithAddress is not able to register a listener with a wildcard in the address as this is not allowed in the OSC specification. As this is the case, every slider would have to register a listener for every client. Once the server has received the message it would would have to extract the client ID from the address and create a new message for each of the other clients with the correct client address.

It would be possible to write a custom OSCReceiver message router to allow the server receiver to listen to wildcard addresses but this means rewriting all of the OSCReceiver stuff! Another option would be to put the clientID as the first argument in every message but this also means copying the message to forward to the other clients.

It would be much simpler if the client didn’t need to put the clientID in the address or arguments. I figured that the server could open a new port for each client and reply with the port number to send to. Then the server will be able to identify the client based on which OSCReceiver it came in on. Alternitively, the OSCReceiver class could provide the source address & port for each OSCMessage received via UDP?

For my multiple port idea to work, I would need OSCReceiver to prevent port reuse so that I could identify an unused port for each client. I am wondering whether it would be a valid case for port reuse to be disabled on OSCReceiver by default or for there to be a method to switch this in the OSCReceiver class.

Cheers,

Chris

I’m not sure what the best approach to managing port reuse is. However, even if this was added to the OSC classes, I think a better solution would only use a single port.

Why do you need to copy the message? Can’t the clients just ignore the first argument? I realise this would increase your bandwidth a little though.

Would being able to obtain the originating IP address of each message solve the problem? We’ve had previous requests for this functionality or similar.

Yes … the client receivers could just ignore the first argument! Perhaps this is the best approach for now!

I think that the originating IP and port would be extremely useful in this scenario. It should remove the need to send additional args in every message to identify the client.

Could you explain why it is better to use a single port? I am not so experienced with these things so would like to understand your reasoning! :slightly_smiling_face:

Oh, there’s no deep reasoning behind that. If you only use a single port you have less chance of using all of the available ones on your system (this was more of a problem several years ago) and it makes other things like service discovery and similar much easier to implement.

1 Like

I want to reuse receiver port between multiple instances of a plugin. However, every time I create an additional instance of the plugin, I cannot connect to the receiver port.

I have already tried with DatagramSocket::setEnablePortReuse. DatagramSocket requires to bind to a port. In additional instances I cannot bind.

The OSC receiver is implemented in the constructor of AudioProcessorEditor in a similar fashion as the tutorial of OSC protocol implementation.

UPDATE:
Sharing the DatagramSocket via SharedResourcePointer works OK. OSC Receiver different behaviour between VST3 and AU

1 Like

I’m also trying to bind multiple receivers to the same port, however, these receivers are not necessarily implemented in instances of the same plugin, but rather in different apps. For now, I tried to modify the OSCSenderTutorial in order to connect both the OSCReceiverTutorial and the OSCMonitorTutorial apps at the same time, without success.

Ideally, I’m looking for a way to send an OSC message from a master app, received by as many slaves as possible, in different apps, or even on other devices in the network (broadcasting).

But I’m stuck at that port reuse step. May SharedResourcePointer also be a solution, or does this trick only work for instances of the same app? Am I maybe thinking it wrong, and it is not possible to bind multiple apps to the same port? Is my only solution to open a new port for each new slave then?

Thank you!

Hi everyone, are there any updates on adding TCP support to OSC?

Hi everyone,

I have a problem similar to the one that was discussed here. I have UDP communication in my application. When an app instance is started, the receiver socket is bound to a port number. I would like to identify if a particular port number is already used by another app instance, and bind the socket to an available port number.

The problem is that in the constructor of the DatagramSocket the port reuse is enabled by default. I would like to disable it, to get false return value from the bindToPort method if the port is already in use. However calling the setEnablePortReuse(false) method does not seem to work, I can only achieve this by removing the SocketHelpers::makeReusable call in the constructor of the DatagramSocket.

Why is the port reuse enabled by default in the constructor? How could it be solved without the modification of the JUCE code?

Thank you!

Rajmund

3 Likes