mrRay / vvopensource

OSC and MIDI frameworks for OS X and iOS, a framework for managing and rendering to GL textures in OS X, and a functional ISF (interactive shader format) implementation for OS X.
231 stars 33 forks source link

OSC Protocol & Ports Clarification #27

Open PusherLabs opened 7 years ago

PusherLabs commented 7 years ago

Noob questions inbound! I think I have things set up correct, but I'm seeing no return traffic. Here's the situation...

First ?, I see the the protocol code at the top of OSCManager.h is all commented out. VVMIDI doesn't work without the protocol in place, so I'm double checking on that it's needed or not for VVOSC?

I have a pretty normal situation where I need to send data over port X and then listen for responses on that same port coming from the destination hardware: sourceip:sourceport <---> destip:destport

The hardware automatically responds to the same port I used to send the data. So when I create the INPort it needs to match the port the OUTPort uses to send data FROM. My question is, when I am SENDING a message how do I specify the port the message gets sent FROM, i.e. the "sourceport" above?

oscManager = [[OSCManager alloc] init]; [oscManager setDelegate:self]; oscInPort = [oscManager createNewInputForPort:sourcePort]; oscOutPort = [oscManager createNewOutputToAddress:destIP atPort:destPort]; OSCMessage *msg = nil; msg = [OSCMessage createWithAddress:@"/some/address"]; [msg addFloat:12.34]; [oscOutPort sendThisMessage:msg];

This gets the message to the hardware successfully, but nothing is being received back from the hardware. I can also see that my program opens another random UDP port each time I run the above.

Thanks!

PusherLabs commented 7 years ago

In OSCOutPort.h the struct:

struct sockaddr_in addr;

... seems to be purely informational. In (BOOL) createSocket, since you're not using addr to pass to a socket bind() call, you're setting it's properties afterwards. Line 98 sets the source local port to OSCOutPort.port, which is the DESTINATION port:

addr.sin_port = htons(port);

Unless I'm missing something (entirely possible), that's NOT the local port created by the socket() call. Granted it won't affect anything, because that struct is informational. It'd be great if we can optionally bind() the sending port.

mrRay commented 7 years ago

First ?, I see the the protocol code at the top of OSCManager.h is all commented out.

those are doxygen comments, here's the HTML that is compiled from the page you referred to (this is within the documentation linked to on the repos' main page):

http://www.vidvox.net/rays_oddsnends/vvopensource_doc/interface_o_s_c_manager.html

I have a pretty normal situation where I need to send data over port X and then listen for responses on that same port coming from the destination hardware:

i wouldn't say that's "normal" because it's assuming that the OSC spec includes provisions on "responding" to OSC messages when it very definitely does not (several proposals have been advanced along these lines over the years but nothing has really "stuck").

that being said, i'm just some guy on the internet and i'm not qualified to say what is or isn't "normal"- and even if i was, sometimes you just gotta get weird, and that's okay too. here's how you do this:

In OSCOutPort.h the struct:

struct sockaddr_in addr;

... seems to be purely informational.

OSCOutPort describes an OSC destination that was either automatically detected by the framework via bonjour/zeroconf, or manually created by the user to refer to an OSC destination that may not be on the local network. the addr variable of an OSCOutPort instance stores the destination address- it's not a vestigal variable, and it's used any time OSC data is sent from the out port.

Unless I'm missing something (entirely possible), that's NOT the local port created by the socket() call.

nope, i think you've pretty much hit the nail on the head- "out ports" bind a socket to an arbitrary (system-assigned) port, from which your data will be sent. "in ports" bind a socket to the user-specified port, which they listen to.

It'd be great if we can optionally bind() the sending port.

question: what effect- if any- would this change have on performance in situations where massive amounts (tens/hundreds of thousands of OSC messages per second) are being received and need to be echoed out to one or more destinations?

i'll try to set up a quick benchmark for this in the next few days...

PusherLabs commented 7 years ago

_dispatchQuery works fabulously.

OSCOutPort describes an OSC destination that was either automatically detected by the framework via bonjour/zeroconf, or manually created by the user to refer to an OSC destination that may not be on the local network. the addr variable of an OSCOutPort instance stores the destination address- it's not a vestigal variable, and it's used any time OSC data is sent from the out port.

I thought the _in part of struct sockaddr_in structure was meant (not in VV specifically, but in general) to describe a local socket. In OSCInPort, VVOSC uses it to describe the local socket and uses it to bind the port. But in OSCOutPort it's used to describe the destination socket because there isn't a local bind taking place. I'd argue that it shouldn't be used to describe the destination socket, evidenced by the fact that you would use struct sockaddr_in to bind the local socket even in OSCOutPort, if you chose to do so , as some other socket libraries do.

We'd need to add a int localPort and setter, then only perform the bind() in (BOOL)createSocket() if localPort is set. Are any other classes using OSCOutPort's private version of addr?

question: what effect- if any- would this change have on performance in situations where massive amounts (tens/hundreds of thousands of OSC messages per second) are being received and need to be echoed out to one or more destinations?

Are you saying this because of the example _dispatchQuery method you posted using the OSCInPort to send messages?

I do have to say, in the past few days, I've checked out F53OSC, OSCKit, and a few others and much prefer VVOSC for the clarity of the code and appreciate it not using GCD. :)