I am developing an App using the Networking framework, which can be either a Socket Server or a Socket Client, such that 2 devices can communicate remotely. For the most part I have it working, except:
I am not sure of the best way to determine the IP Address for the Socket Server in order to allow the Client app to connect. I am currently using either of Cloud Functions, or lookup webpages (such as ipify.org) and even reading the IP addresses locally from within the device (this returns many, but not all of them connect successfully). These options seem to work if the Socket Server app is connected to the internet with an IPv6 address, but I find that when the Socket Server app is connected with an IPv4 address, the Client app never successfully connects.
How should I: a) force the Socket Server app to have/use an IPV6 address at all times? or b) allow the Client app to connect successfully via an IPv4 address?
And is there a simple way to know what IP Address the Socket Server is listening from?
Right, so achieving these goals is a serious challenge. The problem is that device-to-device connections are often not feasible on the modern Internet. The canonical blocker here is NAT.
Imagine you have two devices, A and B, and they’re both behind a NAT. Each device has a private IP address, for example, something on the 192.168.0.0/16 network. When A makes an outgoing connection, the NAT establishes a mapping between A’s private source IP and port and the NAT’s public IP and port. Prior to A making that connection, this mapping doesn’t exist, so B can’t make an incoming connection to A.
In the case of NAT there are well-known techniques to get around this (see NAT traversal) but those only work in specific circumstances. And NAT is not the only challenge here. These days the Internet is full of middleboxen, and those prevent this sort of device-to-device connection in general. And don’t get me started on proxies |-:
Note The reason why you’re seeing this work in the IPv6 case is that IPv6 has lots of addresses and so doesn’t rely on NAT. However, that’s not a solution in general. Not all networks support IPv6 and, even if they do, these connections can be block by some other middlebox, like a firewall.
As to what you should do, that depends on the nature of your product. Is this a game perchance?
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"