Android Клиент подключается только к моему ПК - C# WCF - Ответ 17217172

1) Суть приложения: Что-то на подобии мессенджера, где клиент отправляет сообщение, а сервер выводит его на консоль.

2) Используемые библиотеки: SuperSimpleTcp, что позволит в несколько строк создать клиента/сервера и отправить сообщение. NetFwTypeLib для создание правила в брандмауэре для порта, потому что иначе на разных устройствах клиент не коннектится (ну или сервер не принимает входящих соединений), к тому же на github nuget Пакета "SuperSimpleTcp" я нашел пункт, в котором говорится: Добавить правило в брандмауэр.

3) В чем заключается проблема: Все работает безупречно, если клиент - это андроид в той же сети что и мой пк. И Все не работает когда сервер - это пк друга, находящийся на большом расстоянии от меня. В чем именно проблема, я не понимаю. Если рассмотреть тот случай, когда пк находится на расстоянии от андроид клиента, то как я понял, сервер запускается корректно, а вот андройд-клиент-приложение при попытке подключится - крашит, видимо вылетает какое-то исключение (Но скорее всего что-то на подобии time-out).

Также добавлю: это мое первое знакомство с "Клиент и сервер", до этого потратил около недели на попытки запуска сервера и клиента на разных устройствах, ведь корректно они работали только на одном. При этом, в самих видео/статьях/ответах на форумах я не нашел внятных подробностей о том, "А что, если клиент и сервер запущены на разных машинах?".

Пробовал также добавлять правила на входящие и исходящие соединения в брандмауэре на пк друга вручную, но исход - тот же.

В нетерпении буду ждать ваших ответов, заранее спасибо.

Сервер (Консоль):

C#Выделить код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

using System;
using SuperSimpleTcp;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using NetFwTypeLib;
using System.Text;
 
namespace ConsoleApp6
{
    class Program
    {
        private static string ip = "";
        private static string port = "9120";
 
        static void Main(string[] args)
        {
            OpenMyPort(); //Добавление правила для порта в брандмауэре
 
            Console.Write("Введите ip: ");
            ip = Console.ReadLine();
 
            SimpleTcpServer server = new SimpleTcpServer($"{ip}:{port}");
            server.Start(); //Запуск сервера
 
            server.Events.ClientConnected += ClientConnected;
            server.Events.ClientDisconnected += ClientDisconnected;
            server.Events.DataReceived += DataReceived;
 
            Console.WriteLine("Server is started");
            while(true)
                Console.ReadKey(true);
        }
 
        static void ClientConnected(object sender, ConnectionEventArgs e)
        {
            Console.WriteLine($"[{e.IpPort}] client connected");
        }
 
        static void ClientDisconnected(object sender, ConnectionEventArgs e)
        {
            Console.WriteLine($"[{e.IpPort}] client disconnected: {e.Reason}");
        }
 
        static void DataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine($"[{e.IpPort}]: {Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count)}");
        }
 
        static void OpenMyPort()
        {
            Type type = Type.GetTypeFromProgID("HNetCfg.FwMgr", false);
            INetFwMgr mgr = (INetFwMgr)Activator.CreateInstance(type);
 
            INetFwProfile profile = mgr.LocalPolicy.CurrentProfile; // Получаем текущий профиль
 
            // Создаем и настраиваем правило брандмауэра
            INetFwOpenPort rule = (INetFwOpenPort)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWOpenPort"));            
            rule.Port = port; // Номер порта, который нужно открыть
            rule.Name = "MyPortRule"; // Название правила
            rule.Enabled = true;
 
            // Добавляем правило к профилю
            profile.GloballyOpenPorts.Add(rule);
 
            Console.WriteLine($"Порт {port} открыт");
        }
    }
}

Клиент (Xamarin.Forms):

C#Выделить код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using SuperSimpleTcp;
using System.Diagnostics;
 
namespace AndroidClinet
{
    public partial class MainPage : ContentPage
    {
        Entry input = new Entry(); //поле для ввода сообщения
        Entry inputIp = new Entry(); //поле для ввода IP
 
        private static string ip = "";
        private static string port = "9120";
 
        SimpleTcpClient client;
 
        public MainPage()
        {
            InitializeComponent();
        }
 
        protected override void OnAppearing()
        {
            StackLayout layout = new StackLayout();
 
            Button button1 = new Button(); //Кнопка для отправки сообщения
            button1.Text = "Отправить сообщение";
            button1.BackgroundColor = Color.Orange;
            button1.TextColor = Color.White;
            button1.Clicked += (sender, args) => SendMessage();
 
            Button button2 = new Button(); //Кнопка для коннекта
            button2.Text = "Connect";
            button2.BackgroundColor = Color.Red;
            button2.TextColor = Color.White;
            button2.Clicked += (sender, args) => Connect();
 
            input.Placeholder = "Введите сообщение: ";
            input.IsPassword = false;
 
            inputIp.Placeholder = "Введите ip: ";
            inputIp.IsPassword = false;
 
            layout.Children.Add(button1);
            layout.Children.Add(input);
 
            layout.Children.Add(button2);
            layout.Children.Add(inputIp);
 
            Content = layout;
        }
 
        private void Connect()
        {
            ip = inputIp.Text;
 
            client = new SimpleTcpClient($"{ip}:{port}");
            client.Connect();
            client.Events.Connected += Connected;
            client.Events.Disconnected += Disconnected;
        }
 
        private void SendMessage()
        {
            client.Send(input.Text);
            input.Text = "";
        }
 
        static void Connected(object sender, ConnectionEventArgs e)
        {
            Console.WriteLine($" Server {e.IpPort} connected");
        }
 
        static void Disconnected(object sender, ConnectionEventArgs e)
        {
            Console.WriteLine($" Server {e.IpPort} disconnected");
        }
    }
}

Вернуться к обсуждению:

Android Клиент подключается только к моему ПК C# WCF