Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSC Protocol & Ports Clarification #27

Open
PusherLabs opened this issue May 12, 2017 · 3 comments
Open

OSC Protocol & Ports Clarification #27

PusherLabs opened this issue May 12, 2017 · 3 comments

Comments

@PusherLabs
Copy link

PusherLabs commented May 12, 2017

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
Copy link
Author

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
Copy link
Owner

mrRay commented May 14, 2017

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:

  • make an OSCManager.
  • make an OSCInPort- this is the port that you're going to "listen on".
  • make an OSCOutPort for the destination you want to send OSCMessages to (or let the framework make one for you if the remote hardware supports bonjour/zeroconf).
  • make an OSCMessage you want to send.
  • call -[OSCInPort _dispatchQuery:(OSCMessage *)m toOutPort:(OSCOutPort *)op]. this will use the socket/port you bound on your "listener" to send the message to the given out port.

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
Copy link
Author

_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. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants