0

I have this console app websocket server:

Console.WriteLine("[SERVER]");

TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
server.Start();
Console.WriteLine("Server has started on {0}.{1}Waiting for a connection...", server.LocalEndpoint, Environment.NewLine);

TcpClient client = server.AcceptTcpClient(); //wait for client to connect
Console.WriteLine("A client connected.");

NetworkStream stream = client.GetStream(); //communication channel with client

How can I connect to the console app server in an Xamarin.Android app?

I have tried this (inside xamarin android app, click event for button): But I get an exception from 'client.Connect("127.0.0.1", 80);'

Exception = System.Net.Sockets.SocketException: Connection refused

requestSpeak.Click += (o, e) =>
{
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 80); //connect to sv
NetworkStream stream = client.GetStream(); //communication channel with server
};
t3ch3
  • 71
  • 11
  • 1
    You have to use internal IP, not loopback – Sasha Jul 31 '18 at 13:59
  • Use 10.0.2.2 https://stackoverflow.com/a/51602942/4984832 – SushiHangover Jul 31 '18 at 14:09
  • @SushiHangover it doesn't establish a connection and just times out eventually (System.Net.Sockets.SocketException: ) – t3ch3 Jul 31 '18 at 14:19
  • @Jaxi I tried my local internal ip, 192.168.x.x. My code worked with two console apps, but doesn't work with xamarin android app and console app. – t3ch3 Jul 31 '18 at 14:20
  • 1
    Are you running your xamarin program via an emulator or an actual device? And is it android, UWP, or iOS? – Sasha Jul 31 '18 at 14:25
  • @Jaxi Actual device, android. Nexus 9 (Android 7.1 - API 25) – t3ch3 Jul 31 '18 at 14:26
  • @t3ch3 10.0.2.2 is only for Android emulator, if you are using a device and trying to connect to a "private" IP address then the device needs to be on the same wireless subnet (or connected to a wireless AP+router that is routing between those two subnets of the device and your web socket server host) – SushiHangover Jul 31 '18 at 14:29
  • @SushiHangover hmm okay, my device and pc are on the same network though. – t3ch3 Jul 31 '18 at 14:46
  • @t3ch3 Connect the device to your PC/Mac and use `adb shell` and try to ping your websocket server from "within" Android – SushiHangover Jul 31 '18 at 14:48
  • @SushiHangover Sorry been trying to ping adb shell, haven't worked it out yet :(, but in the meantime while I work on it, is there any other solutions I should consider so the console app and android app can send/receive messages, been stuck on this for 2 days now :/ – t3ch3 Jul 31 '18 at 15:24
  • @t3ch3 So if you use `adb shell ip addr show wlan0` is the IP address shown on the same subnet as your web socket host? – SushiHangover Jul 31 '18 at 15:29
  • @SushiHangover Okay finally got it to work! When I try ping the websocket server within Android it works, all packets transmitted and recieved. – t3ch3 Jul 31 '18 at 20:07
  • @SushiHangover the ip addr show wlan0 shows a different IP address – t3ch3 Jul 31 '18 at 20:08
  • @SushiHangover I made some progress. Using the pc's local ip from ipconfig and being on the same network, it works when I deploy it inside of Visual Studio (debug). However, when I dc the device (phone) and open the installed app (not through vs and debug) on same network it doesn't work. – t3ch3 Jul 31 '18 at 20:25
  • @SushiHangover Sorry for spam, can't edit my last comment again. It actually looks like it works, using pc local ip from ipconfig and on same network. I can unplug the phone and the app will still connect and send messages to the server :) – t3ch3 Jul 31 '18 at 21:02

1 Answers1

0

Irrespective of whether you're using an emulator or a hardware device the mobile app will effectively be seen as an external device on the network. There are many ways to do this, but for development I prefer to download Fiddler and set up a reverse proxy as described in this document. So after turning on "Allow remote computers to connect" I add a rule such as this as the first line of the OnBeforeRequest function:

if (oSession.host.toLowerCase() == "192.168.0.5:8888") oSession.host = "127.0.0.1:80";

...where 192.168.0.5 is the IP address of the machine running the console app. If you've set things up properly then you should also be able to hit 192.168.0.5:8888 from the mobile phone's browser.

Like I said, there are other ways to do this but I find that this one works well because you can change the rule to instead direct to localhost:someport, which is what MVC apps will use by default for local debugging; run a Xamarin app (say) in the VS emulator and it means you can debug both the mobile app and the server code from within the same project. And by redirecting all traffic through Fiddler you can see each and every packet that goes between your mobile app and the server, with full support for JSON, images and both compressed and SSL content.

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • 1
    Could always just use the computers hostname too :) – Sasha Jul 31 '18 at 14:53
  • thanks for answer, but I was looking for a solution without any tools/programs, and from my understanding this is just for debugging and won't be used for release so leaves me with the same issue? :D – t3ch3 Jul 31 '18 at 15:06