In my setup I have 2 apps. One running on my local emulator on my macbook. The other on my physical android phone.
In these apps I use ZeroMQ to have a Req/Rep socket, which under the hood uses TCP.
When hosting my server on the emulated device using port 6543, with it's IP at wlan0 I cannot connect to it from my phone. Reversing the roles works fine where the phone hosts the server and emulator connects to it, but in the long run I need emulators to run this server. Eventually iOS developers want to talk to an Android server, so I'd prefer to keep them using emulators for this.
My understanding is that android emulators exist behind a virtual router, so if you want to talk to them you have to use port forwarding.
I've done this for my emulator. Using redir add tcp:7654:6543. If I understand this correctly then port 7654 of my Macbook should have its traffic redirected to port 6543 of my emulator.
Rather than connect directly to the IP of wlan0 on my emulator, I believe I should be using the IP of my Macbook. For this I run ifconfig | grep "inet " and connect to the IP address that comes back here.
Trying to receive packets in my app though I still don't see traffic.
Additionally I installed Wireshark and filter on tcp.port == 7654 on the wifi interface of my Macbook. While I do see some messages I'm not sure if what I'm seeing is my message itself, or just the TCP handshake as I see multiple SYN and [RST, ACK] but not clear if I should actually be able to see the payloads I'm sending?
I'm not sure at this point what to do. How can I actually verify the traffic is getting to my macbook ok? and how can I verify the forwarding is setup correctly?
So it turns out there are quite a few steps to solve this.
First we have to do the port forwarding as mentioned in the official android docs so we can get messages to the emulator:
in a terminal run
adb devicesto get the port of the deviceYou'll then need to run
telnet localhost 5554using the port that the device is on.From here you'll be prompted for an auth key:
Do as the prompt says, open a second terminal and look at the file to get your token.
Back in the first terminal you'll need to execute
auth <your_token>Then you can setup your port forward
redir add tcp:8765:7654This redirects from the loopback port of your Macbook "8765" to the android emulator port "7654".
Now you have to redirect from your Macbook public IP to its internal loopback address.
First go to
System Preference -> Sharing -> enable Remote Loginso that we can setup a port forward using SSH.While the SSH requires authentication, and with turning on I'm guessing there may be some security concerns as you're opening up your laptop to external traffic. This may be somewhere to research more before you proceed.
If this is ok you can then run
ssh -v -g -L 9876:localhost:8765 localhostwhich will then run in the terminal and perform the forwarding for you.The final result is:
macbook_ip:9876forwards tomacbook_loopback_ip:8765forwards toandroid_emulator:7654On the Emulator side you have to bind to one of its addresses automatically assigned by the OS:
10.0.2.15:7654And on the physical device side you connect to the Macbook IP:port. This number you'll need to look up yourself by running
ifconfig | grep "inet "As an example you may connect to something like this:
10.0.0.253:9876At this point you should have your physical Android phone able to send messages to, and receive from the socket you bound in your Emulator.