Network.framework and port 9999 unreachable

Hello

I'm using the Network framework to communicate with an IoT device via its built in hotspot using UDP. Communication works great when using port 7777 however some devices with older firmware use port 9999 and the communication there is strictly one sided, the device receives the command but the app never receives a response.

I fired up WireShark and interecepted the traffic, the device/remote host sends a response but it is never received by the app and in WireShark I see an error that the port (9999) is unreachable. Anyone know if this is intentionial, as I said, the same code works fine on port 7777.

Accepted Reply

The only time I'm setting a port number is when I assign the

NWConnection
as follows

OK, this only sets the remote peer’s port. The local peer will use a dynamically assigned port.

And the hardware I am connecting to sends the response to port 9999 so there is really no avoiding that.

OK, I’m confused. If the code you posted works with 7777, then the 7777 service doesn’t send its response to port 7777 because that code doesn’t set the local peer’s port.

My best guess here is that your two services behave differently:

  • Port 7777 sends its response to the remote peer’s port, which is how things should work.

  • Port 9999 always sends its response to port 9999, which is deeply suboptimal. Then again, you did mention that this is the legacy service, and perhaps that’s why.

Regardless, if you need to bind the connection’s local port to 9999 you can do that using the

requiredLocalEndpoint
parameter.
let parameters = NWParameters.udp
parameters.requiredLocalEndpoint = NWEndpoint.hostPort(host: .ipv6(.any), port: 9999)
let conn = NWConnection(host: "192.168.4.1", port: 999, using: parameters)

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

In UDP communication both the local and remote peers have a port number. Given this:

however some devices with older firmware use port 9999

it seems like 9999 is the remote peer’s port number. Are you also using it as the local peer’s port number? If so, do you have to? In most UDP protocols it’s fine to use a dynamically allocated local port number.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for the response.

The only time I'm setting a port number is when I assign the NWConnection as follows


var connection: NWConnection = NWConnection(host: "192.168.4.1", port: 9999, using: .udp)


Do I need to create a listener? I haven't had to do that with port 7777 so I don't know why 9999 would be any different.


And the hardware I am connecting to sends the response to port 9999 so there is really no avoiding that.


thanks again

The only time I'm setting a port number is when I assign the

NWConnection
as follows

OK, this only sets the remote peer’s port. The local peer will use a dynamically assigned port.

And the hardware I am connecting to sends the response to port 9999 so there is really no avoiding that.

OK, I’m confused. If the code you posted works with 7777, then the 7777 service doesn’t send its response to port 7777 because that code doesn’t set the local peer’s port.

My best guess here is that your two services behave differently:

  • Port 7777 sends its response to the remote peer’s port, which is how things should work.

  • Port 9999 always sends its response to port 9999, which is deeply suboptimal. Then again, you did mention that this is the legacy service, and perhaps that’s why.

Regardless, if you need to bind the connection’s local port to 9999 you can do that using the

requiredLocalEndpoint
parameter.
let parameters = NWParameters.udp
parameters.requiredLocalEndpoint = NWEndpoint.hostPort(host: .ipv6(.any), port: 9999)
let conn = NWConnection(host: "192.168.4.1", port: 999, using: parameters)

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you! This seems to have resolved my issue as I'm now seeing the response on the phone.