TCP + UDP connections via Bonjour

For a local video streaming app I want to establish both a TCP and a UDP NWConnection. What is the best way to do this using Bonjour? Do I advertise separate Bonjour services for TCP and UDP? Or if I just advertise one (say TCP), what is the best way of creating a new UDP NWConnection to the same device once the TCP connection has been established?

Replies

Do I advertise separate Bonjour services for TCP and UDP?

That’s likely to be the easiest option.

Or if I just advertise one (say TCP), what is the best way of creating a new UDP NWConnection to the same device once the TCP connection has been established?

It kinda depends on how you set things up. When you go to establish the UDP connection you need to supply two bits of info:

  • Address

  • UDP port

You can get the first from the currentPath property of the TCP connection (connection.currentPath?.remoteEndpoint). The problem is the second. What port should you use?

If your service is set up so that it always listens to TCP and UDP on the same port, that’s fine. If not, you need a way to discover the UDP port, and the best way to do that is by advertising it using Bonjour.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you! Actually the second option sounds slightly easier to me. At least that way I am 100% guaranteed that both connections talk to the same device. Is there a downside to just picking some fixed port number (say 649) and using that for the UDP connection? Is there a risk that some wireless routers (I am just connecting locally) would block that port and Bonjour would find a non-blocked port?

Is there a downside to just picking some fixed port number (say 649) and using that for the UDP connection?

Do not do that. Low-numbered ports are allocated by IANA. The verges of the information super-highway are littered with the roadkill of folks who thought “I’ll just borrow this allocation for my little project. No one will notice.”

There are a couple of ways you might approach this:

  • Allocate a TCP port dynamically, then try to allocate the same port on UDP, and loop on failure.

  • Allocate a UDP first and then put its port number in the TXT record of your TCP listener.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Allocate a TCP port dynamically, then try to allocate the same port on UDP, and loop on failure.

Thank you. That sounds like a reasonable plan to me. What does 'loop on failure' mean? Repeatedly try to listen and connect on the same port? How likely is failure in this scenario (local connection between two devices with Bonjour providing the TCP connection).

What does 'loop on failure' mean?

If you can’t allocate a UDP listener with a port that matches your TCP listener, abandon the TCP listener and start again from scratch. Your TCP listener will then get a new port and, statistically, it’s matching UDP port will be available.

This, btw, was standard practice with BSD Sockets for setting up a TCP listener that works on IPv4 and IPv6.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"