dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.36k stars 4.75k forks source link

TcpClient not working with maui when there is multiple connection #106149

Open lkhore opened 3 months ago

lkhore commented 3 months ago

Description

TcpClient not working with Maui when there is multiple connection like with wifi and mobile internet so TcpClient always connect to mobile internet not with wifi local n/w like below code

public async Task ConnectUsingTcpClientAsync(string serverAddress, int port)
{
    var localAddress = IPAddress.Parse("192.168.0.100");
    // Create a socket and bind it to the local address
    var localEndPoint = new IPEndPoint(localAddress, 0);
    using (var socket = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, ProtocolType.Tcp))
    {
        // Bind the socket to the local IP address
        socket.Bind(localEndPoint);

        // Create TcpClient using the socket
        using (var client = new TcpClient(new IPEndPoint(IPAddress.Any, 0)))
        {
            // Assign the socket to TcpClient
            client.Client = socket;

            try
            {
                // Connect to the server
                await client.ConnectAsync(serverAddress, port);
                Console.WriteLine("Connected successfully over the specified network interface.");
            }
            catch (SocketException ex)
            {
                Console.WriteLine($"Connection error: {ex.Message}");
            }
        }
    }
}

Steps to Reproduce

No response

Link to public reproduction project repository

No response

Version with bug

8.0.80 SR8

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

8.0.0-rc.1.9171

Affected platforms

Android

Affected platform versions

No response

Did you find any workaround?

no

Relevant log output

there is no output file
jfversluis commented 3 months ago

Don't see anything MAUI specific here. I would think this is a runtime issue then.

dotnet-policy-service[bot] commented 3 months ago

Tagging subscribers to this area: @dotnet/ncl See info in area-owners.md if you want to be subscribed.

wfurt commented 3 months ago

why do you Bind on specific IP? I'm not sure about android but generally this will limit outgoing interface AFAIK. The routing logic is handled by OS kernel and besides the bind I don;t see anything that can be impacted but .NET Sockets. cc @simonrozsival

lkhore commented 3 months ago

I have scenarios where my mobile device is simultaneously connected to both Wi-Fi and mobile internet. The Wi-Fi network doesn't have internet access but is connected to IoT devices, so I need to make sure that calls are routed through the Wi-Fi network interface. However, the device often defaults to using the mobile internet connection instead.

simonrozsival commented 3 months ago

@lkhore I wasn't able to reproduce this issue on my Android device (Samsung, API 34). I can successfully connect to the server with your code snippet. Can you share more information about your setup?

lkhore commented 3 months ago

I have a Redmi 12 5G. First, I need to enable mobile data on my device and then connect to a Wi-Fi network that doesn't have internet access but does have IoT capabilities. Both mobile data and Wi-Fi should be connected simultaneously. After that, when I try to create a TcpClient connection over the Wi-Fi, there's no connection because the network traffic is being routed through mobile data instead of the Wi-Fi."

simonrozsival commented 3 months ago

there's no connection because the network traffic is being routed through mobile data instead of the Wi-Fi

Can you confirm that when you try running adb shell ping <server-address> and adb shell ping -I wlan0 <server-address>, the device can actually reach the server?

Can you also please give us more details about what exactly isn't working? Is ConnectAsync never awaited or does it throw an exception? If it throws an exception, please share it with the stack trace.

lkhore commented 3 months ago

Below are the ping result C:\Users\LKhore>adb shell ping -I wlan0 192.168.0.1 ping: SO_BINDTODEVICE: Operation not permitted

C:\Users\LKhore>adb shell ping 192.168.0.1

adb shell ping 192.168.0.1 is not gave any result

Below is the exception i got from code snippet

{System.Net.Sockets.SocketException (110): Connection timed out at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state) --- End of stack trace from previous location --- at System.Net.Sockets.TcpClient.CompleteConnectAsync(Task task) at MauiMobileAppServices.MainPage.ConnectUsingTcpClientAsync(String serverAddress, Int32 port) in D:\Repo\KKService8\MauiMobileAppServices\MainPage.xaml.cs:line 138}

simonrozsival commented 3 months ago

I am not able to replicate your network setup here, but I am able to bind ping to a specific network interface:

Simons-MacBook @ ~   
>_ adb shell ping -c 1 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=58 time=44.2 ms

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 44.284/44.284/44.284/0.000 ms

Simons-MacBook @ ~   
>_ adb shell ping -c 1 -I wlan0 1.1.1.1
PING 1.1.1.1 (1.1.1.1) from 10.105.96.84 wlan0: 56(84) bytes of data.

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

Simons-MacBook @ ~   
>_ adb shell ping -c 1 -I rmnet_data0 1.1.1.1
PING 1.1.1.1 (1.1.1.1) from 10.82.253.40 rmnet_data0: 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=58 time=382 ms

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 382.329/382.329/382.329/0.000 ms

Simons-MacBook @ ~   
>_ adb shell ping -c 1 -I rmnet_data2 1.1.1.1
PING 1.1.1.1 (1.1.1.1) from 10.144.57.214 rmnet_data2: 56(84) bytes of data.

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

It seems that your device doesn't permit binding to a specific network interface. If you can't bind with ping in shell, I wouldn't expect you to be able to do so in .NET.

Also, it seems that your IoT device is not reachable from your phone if you can't ping it without restricting the interface. I suspect there is some problem in your networking setup (firewall?) that prevents you from talking to the other device and that makes me believe the issue is not specific to .NET.

lkhore commented 3 months ago

But I can ping when i connect with the same wifi only without connecting to the internet and also this can be reproducible in some other mobile as well.

simonrozsival commented 2 months ago

But I can ping when i connect with the same wifi only without connecting to the internet and also this can be reproducible in some other mobile as well.

I must admit I'm a little confused. In your previous comment, based on the output you posted, ping wasn't able to reach 192.168.0.1. What is the scenario in which you are able to ping that IP address? I don't see how being connected to the internet can affect whether you can access a device on a local network or not.

lkhore commented 2 months ago

When I ping while connected to both Wi-Fi and mobile internet simultaneously, it doesn't work. However, when I'm connected to only Wi-Fi, it works fine.

wfurt commented 2 months ago

that seems like problem with your local setup. The routing is done by OS kernel and it should follow the most specific route e.g. it should see your local LAN subnet directly connected.

lkhore commented 2 months ago

just to clarify confusion below are details of the phone i am using for testing and responses of ping command along with list of available interfaces:

Issue : not able to bind ping to any particular interface, getting error of "SO_BINDTODEVICE: Operation not permitted"

Requirement : we would like to connect to socket available on Wi-Fi interface(which does not have internet i.e local network) where phone has been connected to internet over differnet interface (either Cellular or USB)


C:\Users\**>adb shell "echo 'Model: ' $(getprop ro.product.model) && echo 'Product Name: ' $(getprop ro.product.name) && echo 'Manufacturer: ' $(getprop ro.product.manufacturer) && echo 'Brand: ' $(getprop ro.product.brand)"
Model:  22111317I
Product Name:  sunstone_in
Manufacturer:  Xiaomi
Brand:  Redmi

sunstone:/ $ ifconfig
rmnet_data1 Link encap:UNSPEC
          inet6 addr: 2402:8100:7076:7243:4800:72ff:fee7:c6f6/64 Scope: Global
          inet6 addr: fe80::4800:72ff:fee7:c6f6/64 Scope: Link
          UP RUNNING  MTU:1600  Metric:1
          RX packets:75734 errors:0 dropped:0 overruns:0 frame:0
          TX packets:86695 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:78883027 TX bytes:16100929

rmnet_data2 Link encap:UNSPEC
          inet addr:100.96.89.24  Mask:255.255.255.240
          inet6 addr: fe80::3c21:a3ff:fe9a:717a/64 Scope: Link
          inet6 addr: 2402:8100:3872:402e:3c21:a3ff:fe9a:717a/64 Scope: Global
          UP RUNNING  MTU:1500  Metric:1
          RX packets:171724 errors:0 dropped:0 overruns:0 frame:0
          TX packets:160670 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:385559502 TX bytes:26803534

wlan0     Link encap:UNSPEC    Driver icnss2
          inet addr:192.168.0.100  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::fc76:c0ff:fee4:e58f/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:24940278 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6749812 errors:0 dropped:84 overruns:0 carrier:0
          collisions:0 txqueuelen:3000
          RX bytes:22953859392 TX bytes:1501244968

rmnet_data0 Link encap:UNSPEC
          inet6 addr: fe80::bcf6:cdff:fef8:4230/64 Scope: Link
          UP RUNNING  MTU:1500  Metric:1
          RX packets:933 errors:0 dropped:0 overruns:0 frame:0
          TX packets:895 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:62796 TX bytes:60546

dummy0    Link encap:UNSPEC
          inet6 addr: fe80::ac84:cdff:fe57:918e/64 Scope: Link
          UP BROADCAST RUNNING NOARP  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:25846 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 TX bytes:3885086

rmnet_ipa0 Link encap:UNSPEC
          UP RUNNING  MTU:9216  Metric:1
          RX packets:358680 errors:0 dropped:0 overruns:0 frame:0
          TX packets:722928 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:737258715 TX bytes:107416317

lo        Link encap:UNSPEC
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope: Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:2362668 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2362668 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:5875957605 TX bytes:5875957605

sunstone:/ $ ^C
130|sunstone:/ $ ^C
130|sunstone:/ $ exit

C:\Users\LKhore>adb shell ping -c 1 -I wlan0 192.168.0.1
ping: SO_BINDTODEVICE: Operation not permitted

C:\Users\LKhore>adb shell ping -c 1 -I rmnet_data0 1.1.1.1
ping: SO_BINDTODEVICE: Operation not permitted

C:\Users\LKhore>adb shell ping -c 1 -I rmnet_data0

C:\Users\LKhore>adb shell ping -c 1 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=57 time=257 ms

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 257.526/257.526/257.526/0.000 ms

C:\Users\LKhore>adb shell ping -c 1 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.

--- 192.168.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms