Jak ustanowić połączenie klient serwer klient będących w innych sieciach

0

Witam. Kilka dni temu założyłem post odnośnie bezpieczeństwa przesyłania danych w sieci i naszła mnie myśl, że moja aplikacja klient serwer jest testowana w sieci lokalnej.

O ile serwer będzie widzialny to gdy serwer będzie próbował wysłać wiadomość do klienta firewall odmówi mu dostępu. Wyczytałem, że trzeba przekierować port z routera na nasz lokalny adres IP. Ale czy to jest dobre rozwiązanie? I w jaki sposób to zrobić? Bo nie spotkałem się jeszcze aby któryś program pytał się mnie o hasło i login do routera 😅

Dopiero co zaczynam WCF. Wcześniej operowałem na Windows.SOCKET. Jeżeli odpowiedź znajduje się gdzieś tam powiedzcie to przestudiuję całą dokumentację. Nie chcę po prostu iść po omacku. Dziękuję za wszelką pomoc.

1

Nie bardzo rozumiem. Klient łączy się z serwerem znajdującym się w sieci Internet tak? Po nawiązaniu połączenia serwer wysyła dane do klienta mając już jego adres odpowiednim protokołem. Żadnego przekierowywania portów nie ma potrzeby konfigurować. Jeśli aplikacja korzysta ze standardowych protokołów i klient wyraził zgodę przy komunikacie firewalla, to dalej komunikacja nie powinna sprawiać problemów.

Po co użytkownik po stronę klienta miałby się bawić w przekierowywanie portów zamiast po prostu wyrazić zgodę aplikacji, gdy firewalla o nią zapyta?

No chyba, że masz co innego na myśli, a ja źle zrozumiałem.

0

Czyli jeżeli klient połączył się z serwerem to wystarczy na serwerze zapisać zewnętrzne IP klienta i po problemie?

Z myślą twojej odpowiedzi kolejność jest taka :

  1. Klient wysyła dane do serwera.
  2. Serwer zapisuje IP klienta
  3. Serwer odpowiada na dane.
  4. Użytkownik otrzymuje monit o zezwolenie na transmisję danych na danym porcie.
  5. Co jeżeli to serwer będzie chciał wysłać dane do klienta np. Zgłosić potrzebę wylogowania i otrzymać odpowiedź? Czy klient musi także posiadać localserver? I wtedy jak się z nim połączyć?

Edit:
Nie wiem już czy dobrze to wszystko rozumiem...
https://stackoverflow.com/questions/46843811/c-sharp-public-ip-client-server

  1. Serwer dysponuje zewnętrznym IP klienta oraz portem nasłuchiwania jego lokalnego serwera (bo według mnie musi klient również nasłuchiwać). Czy według osi zewnętrzny adres IP to adres routera a adres Mac to adres urządzenia końcowego? I router powinien mieć ten adres w dhcp.

I w końcu udało mi się ułożyć logiczne pytanie :
W jaki sposób nawiązać połączenie klienta z serwerem będącym poza siecią wewnętrzną, aby później serwer mógł także pełnić rolę klienta i nawiązywać połączenie z lokalnym serwerem użytkownika?

0

Nie ma takiej możliwości, aby się podłączyć do urządzenia, które jest w sieci nieroutowalnej, bez jakiegoś mechanizmu przekierowania portów, czy czegokolwiek. Jeżeli potrzebujesz komunikacji dwustronnej, to nie stawiasz na "kliencie" drugiego serwera - da się wszystko ogarnąć w jednym połączeniu. Nie wiem jak to się robi w WCF, bo nie używam, ale spróbuj np. https://www.c-sharpcorner.com/uploadfile/dhananjaycoder/a-simple-duplex-service-in-wcf/

Czy według osi zewnętrzny adres IP to adres routera a adres Mac to adres urządzenia końcowego? I router powinien mieć ten adres w dhcp.

Tak, "zewnętrzny" adres IP to zazwyczaj adres twojego routera. Serwer DHCP posiada adres MAC urządzenia, które go o adres poprosiło. Ale te dwie rzeczy kompletnie nie mają związku ze sobą, bo w pakiecie IP nie ma nigdzie informacji o adresie MAC. W ogóle serwer DHCP i router w ogóle nie muszą nawet być jednym urządzeniem.

0

@Ktos: udało mi się uruchomić usługę. Jednak nie za bardzo rozumiem jak to działa.
screenshot-20190415234157.png

Pierwsze czego nie rozumiem to plik konfiguracyjny. Co jest w nim zawarte? (Nie wiem, czy czegoś nie spitoliłem w nim :D )

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviors">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="WcfServiceLibrary1.MyService">
        <endpoint address="" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IMyService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/WcfServiceLibrary1/MyService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Drugie czego nie rozumiem to: csharp ServiceHost host = new ServiceHost(typeof(MyService));

Skoro usługa jest uruchomiona po co w poradniku https://adamprescott.net/2012/08/15/a-simple-wcf-service-callback-example/ używa się metody Open() i Close() ?
Dodatkowo przy wywołaniu metody host.Open() otrzymuję wyjątek:

System.InvalidOperationException: „Usługa „WcfServiceLibrary1.MyService” ma zerowe punkty końcowe aplikacji. Może to być spowodowane tym, że nie znaleziono pliku konfiguracji dla aplikacji, nie znaleziono elementu usługi pasującego do nazwy usługi w pliku konfiguracji lub nie zdefiniowano punktów końcowych w elemencie usługi.”```
0

Udało mi się wysłać i odebrać komunikat... Po 24 godzinach męki :D Niestety gdy serwer uruchomię na jednym komputerze a klienta na innym klient nie otrzymuje już wiadomości zwrotnej. Klient się po prostu zawiesza. Zmieniłem:
[Client] App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IStudentService" />
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8733/WcfServiceLibrary1/MyService/"
                       binding="wsDualHttpBinding"
                       contract="WcfServiceLibrary1.IMyService"
                       name="WSHttpBinding_IStudentService">
      </endpoint>
    </client>
    <services>
      <service name="WcfServiceLibrary1.MyService">
        <endpoint address="" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IMyService">
          <identity>
            <dns value="192.168.1.163" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IMyService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.163:8733/WcfServiceLibrary1/MyService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

[Server] App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviors">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="WcfServiceLibrary1.MyService">
        <endpoint address="" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IMyService">
          <identity>
            <dns value="192.168.1.163" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="wsDualHttpBinding" contract="WcfServiceLibrary1.IMyService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.163:8733/WcfServiceLibrary1/MyService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Tutaj jest cała aplikacja. proszę o pomoc

0

Witam,

A nie mógłbym tego puścić normalnie po HTTP/HTTPS (https://www.codeproject.com/Articles/550796/A-Beginners-Tutorial-on-How-to-Host-a-WCF-Service)?

Pozdrawiam,

mr-owl

2

Jak nie rozumiesz pliku konfiguracyjnego, to znaczy, że pora przeczytać dokumentację. ;)
Serio, WCF jest względnie prosty w podstawowej konfiguracji.
Bez poznania podstaw będzie dużo pytań w stylu "dlaczego się zawiesza?", "co oznacza błąd x?", "dlaczego wiadomość nie dochodzi?"
Więc po pierwsze, lecisz np. z tym: link
(I nie chodzi mi tu tylko o stronę, na którą Cię kieruje, po lewej masz całe drzewko z dokumentacją. ;) )
I piszę to na bazie własnych doświadczeń, jak zaczynałem z WCF i "chciałem się pobawić", bez wnikania w dokumentację było to mocno czasochłonne.
Zrozumienie czym jest, jaka działa, do czego można go użyć i jak wygląda jego podstawowa konfiguracja zajmuje z pomocą google zdecydowanie mniej czasu,
niż rozwiązywanie problemów wynikających z braku tej wiedzy. ;)

Co do tego, że się zawiesza -> debuguj!
Tekst: "klient się zawiesza" nic nie mówi. I trochę nie przystoi programiście. :D Tak to może użytkownik napisać.
Wypada wskazać w jakiej konkretnie linijce, jaki błąd rzuca (czy w ogóle), co już Ty z tym zrobiłeś (żeby nikt nie powtarzał bez sensu tego samego szukając rozwiązania)?
Czy w ogóle do klienta dotarła jakakolwiek wiadomość? Czy do serwera dotarła? Wiesz... całe flow tego. ;)
Do tego sprawdź np. dziennik zdarzeń, czy aplikacja cokolwiek zostawiła w nim itd.
Wrzucenie projektu i zrzucenie całej roboty na innych to średni pomysł.
(Chyba, że nie wiesz, jak to debugować, to pisz. ;) )

A co do samej funkcjonalności, to jak ogarniesz podstawy WCF'a to w internecie jest pełno
komunikatorów w różnych konfiguracjach (client - client, client - server - client, itd.).
Fraza: "WCF chat" zwraca sporo. ;)

0

screenshot-20190422023647.png

Udało mi się połączyć z usługą:

Serwer:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <system.serviceModel>
    <services>
      <service name="ClientServerInterface.GsService">
        <endpoint address="" binding="wsDualHttpBinding" contract="ClientServerInterface.IServer"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.163:9090"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Klient:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IServer" />
            </wsDualHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://192.168.1.163:9090/" binding="wsDualHttpBinding"
                bindingConfiguration="WSDualHttpBinding_IServer" contract="GSServer.IServer"
                name="WSDualHttpBinding_IServer">
                <identity>
                    <userPrincipalName value="GS-SERVER\GS-SERVER" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Niestety to działa tylko na lokalnym komputerze. Nie potrafię połączyć jednego komputera klienta z drugim komputerem hosta (ta sama sieć lokalna)

1 użytkowników online, w tym zalogowanych: 0, gości: 1