[Chat] Client -> Client Verbindung mittels Server`s

Alles rund um die Programmierung mit Qt
Antworten
Mineralwater
Beiträge: 29
Registriert: 6. Mai 2009 16:44
Kontaktdaten:

[Chat] Client -> Client Verbindung mittels Server`s

Beitrag von Mineralwater »

Hallo Leute!

Ich programmiere derzeit an einer Chat-Plattform welche aber nicht das gewöhnliche Versenden von Textnachrichten sondern auch Dateien usw. beherrschen soll.

Mein Derzeitiger Gedankenstrang ist folgender und ich hoffe ich ihr habt ein paar Tipps für mich:

Jeder Client meldet sich zunächst am Server an und authentifiziert sich.
Der Server speichert für jeden Clienten individuelle Abwesenheits-Informationen, gibt ihm die FreundeListe aus usw. usw.
Bevor zwei Clienten miteinander chatten können müssen die 2 Clienten sich untereinander kennen (Port & IP) und erfragen somit immer beim erstellen einer neuen Chat-Sitzung den Port und die IP-Adresse des Clienten. Die sollen dann nämlich untereinader direkt schreiben können, ohne das ein Server dazwischen sitzt.

Meine Fragen:

Müsste demnahc nicht die Client-Software mindestens zwei QTcpSocket (Serververbindung & mind. 1 ClientSocket) benötigen?
Zusätzlich noch ein QTcpServer für das Empfangen von Nachrichten eines anderen Clienten?

Wenn ClientA an ClientB schreiben will müsste dann nicht beim Server ClientB ausgewertet werden, so das man die IP & den Port erhällt auf dem der ClientB lauscht?

Wie könnte ich sicherstellen kann das der QTcpServer bei dem Clienten wirklich über das Internet erreichbar ist, ohne das jeder Chat-Benutzer erst eine Port-Weiterleitung am Router setzen muss?

Vielen Dank im vorraus!

Mineralwater
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Du denkst viel zu kompliziert ^^

Netzwerk grundlagen:

- TCP verbindungen sind bidirektional ! also ueber eine Socketverbindung, egal ob client oder server, kannst du lesen und schreiben !

- Server koennen / mussen am selben port mehrere verbindungen entgegennehmen koennen. Im endeffekt wird dir fuer jede verbing mit irgend nem client ein explizieter socket erzeugt, den der server bedient.
Wenn ClientA nun was an ClientB schicken will, bekommt der server am Socket zu client A daten, die muss er auswerten, dann weisser er dass er da was an ClientB schicken muss, also sucht er sich den socket fuer client B und schiesst die daten da rein. Das heisst, das A von B gar nix wissen muss, weil der server vermittelt !
Alternativ kannst den Clients auch die daten des anderen zuschicken (peer to peer), aber egal wie, dann wirst mit router probleme bekommen.
Bei ICQ geht z.b. der direkte datenaustausch(p2p) nicht, wenn hinter nen router sitzt.
Wie könnte ich sicherstellen kann das der QTcpServer bei dem Clienten wirklich über das Internet erreichbar ist, ohne das jeder Chat-Benutzer erst eine Port-Weiterleitung am Router setzen muss?
Gar nicht, ohne den router zu manipulieren !!!
es gibt einige protokolle da muss der router sowas koennen (ftp, die alte art). Dafuer gibt es aber auf dem router routinen, die auf den einem port uebersetzen, d.h. das protokoll verstehen, und dementsprechend dann Daten von dem anderen Port an den anderen rechner durchreichen.
Diese funktionalitaeten gibt es nur fuer ein paar protokolle, sind nicht in allen routern implementiert, und sind dann eh ein und ausschaltbar.
Dieses Design gilt als veraltet ... wird durch andere Einkanal protokolle ersetzt (ftp neueres protokoll), weil die eben unkomplizierter mit routern funktionieren.

Bei allen anderen Faellen musst du immer zuerst vom client eine verbindung nach aussen initieren, um danach daten von aussen ueber die verbindung empfangen zu koennen. So funktioniert nun mal NAT.


Ergo, mit nem "neuen" Protokoll kommst ums Portforwarding ned drumherum, wenn eine p2p verbindung haben willst.

Was spricht gegen die Serverloesung ?
warum ueberhaupt selber was entwickeln, wenn der nutzen im vordergrund steht, und nicht ein Vorhandenes Protokoll und dessen vorhandene Ressourcen zu nutzen ??? Jabber ? ICQ ?

Ciao ...
Mineralwater
Beiträge: 29
Registriert: 6. Mai 2009 16:44
Kontaktdaten:

Beitrag von Mineralwater »

Hey Danke für die klasse Antwort!

Derzeit hab ich`s so gelöst das keine Direktverbindung zwischen den Clienten besteht sondern wie du auch schon beschrieben hast, die Clienten sich am Server anmelden welcher die verschiedenen Sockets verwaltet.

Client A sendet zum Server, dieser Reicht die Daten dann anhand der Socket-Verbindung von ClientB weiter - Klappt auch alles wunderbar, gar keine Frage.

Allerdings war/ist das Interesse natürlich groß die Pakete nicht immer über den Server "durchzuschleifen" auch wenn dies natürlich Vorteile bringt - Anonymität bspw.

Andererseits wird ja bspw. bei Datentransfers eine Direktverbindung (Peer2Peer) vom Vorteil sein, zum einen ja auch großer Traffic beim Server entsteht.

Warum kein vorhandenes Protokoll nutzen?
Bei ICQ (AOL) bspw. bist du mehr oder weniger damit einverstanden das du deine Daten freigibst, und diese für das Unternehmen einlesbar sind. Zum anderen wollte ich tiefer in die C++ Programmierung einsteigen.

Allerdings stelle ich mir dennoch die Frage, wie es andere Programme wie bspw. Teamviewer schaffen Informationen auszutauschen, ohne das diese bei einem Router explizit freigeschaltet werden müssen.
Ausgehend ist klar funktioniert bei normalen Routern immer, aber wie funktioniert es das Informationen auch ohne Port-Freigabe am PC eingehend ankommen?
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

aber wie funktioniert es das Informationen auch ohne Port-Freigabe am PC eingehend ankommen?
wie oben schon beschrieben ... gar nicht !!! Es funktioniert so nicht !
Welche software soll das sein die "sowas" macht ??? Ich denk mal die gehen auch ueber nen vermittlungsserver, bzw muessen einen port durchschalten. Machen alle Protokolle so (emule, bittorrent .... die haben neben dem p2p modus auch den normalen der ueber den server geht, des iss dann lahmer, aber funktioniert . Testen kann es der server, selber, ob die clients p2p koennen, weil er kan andere ports anpingen und die antworten auswerten. wenn beide p2p koennen, bzw beide die ports durchgeleitet haben, vermittelt der server dann auf direkte kommunikation)
So macht es skyp, so macht es ICQ so macht es bittorrent. Wobei das manchmal bissi verwirrend iss, weil du nie 100% weisst ob nen vermittlungsserver dazwischen iss ... bzw, du nicht von nem anderen PC indirekt getriggert wirst.

Bittorent kann z.b. wenn jemand was von dir braucht, und nur der der das braucht direkt am Inet ohne NAT haengt, die verbindung vermitteln, in dem du den TCP transfer startest. Also der Vermittlungsserver kann dir sagen, du, schick die daten an die und die adresse ....
Also am ende braucht fuer eine p2p verbindung nur einer das portforwarding, bzw den direktanschluss.

Nimm dir mal wireshark und schau dir waehrend sowas lauft die tcp header an. da weisst wer was initiert ...

noch mal zum technischen:
egal welcher Port, egal welcher router, egal was, sobald auf dem Router NAT laeuft, kommen Packete vom router nicht zu deinem rechner.
Wie auch ? die packete muessen im Internet mit der IP deines Routers laufen, sonst kommen sie nicht ans ziel ... an deinem router koennen zig rechner im internen netz haengen, an welchen soll er das schicken ???
Er verwirft die dinger alle, selbst wenn am TCP paket irgendwas bissi uneindeutig ist.

deshalb muss immer erst der client aktiv werden, und ne TCP verbindung aufbauen, anhand der IP des clients und einigen TCP internas kann der Router, bzw die NAT implementierung zu den TCP Anfragen die antworten identifizieren, und sie zum richtigen client wieder zurueckleiten.
Dazu baut er sich mehr oder weniger komplexe interne tabellen auf.

Die TCP internas sind wiederum wichtig, falls 2 oder mehr rechner im internen netz zugleich den selben dienst nutzen.
Sonnst koennt er die antowrten des servers zu den 2 oder mehr clients nicht unterschieden die haben ja als zieladresse, port, absenderadresse dann loischer weisse das gleiche. .... und es koennt immer nur 1 im netz grad spielen,

Schwachbruestige router hatten deswegen probleme, wenn viele verbindungen gleichzeitig geoeffnet wurden.
Emule war beruechtigt dafuer, zig verbindungen zu initieren.

Ciao ...
Zuletzt geändert von RHBaum am 11. Februar 2010 17:39, insgesamt 1-mal geändert.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Es gibt da schon eine Möglichkeit, aber dazu fehle 'Mineralwater' einfach die Netzwerkkenntnisse.

Stichwort: Skype
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

was macht skype ?

skype geht bei mir immer ueber nen vermittlungsserver, weil alle meine peers hinter nem NAT liegen und ich auch .... Laut wireshark funk ich nie mit der Off ip adresse meines peers ... sondern immer mit ner anderen !

aus der skype wiki:
Non-firewalled clients and clients on publicly routable IP addresses are able to help NAT’ed nodes to communicate by routing calls. This allows two clients who otherwise would not be able to communicate to speak with each other. Because the calls are encrypted end-to-end, proxies limit the security or privacy risk.
Ciao ...
Mineralwater
Beiträge: 29
Registriert: 6. Mai 2009 16:44
Kontaktdaten:

Beitrag von Mineralwater »

Ich hätte sonst noch ein Stichwort welches "UPnP" lautet, konnte allerdings leider keine genaueren Informationen im Zusammenhang mit der Programmierung finden.

Wie es scheint werde ich`s dann wohl so lösen, dass der Client standardmäßig versucht nen TcpServer auf einen optional wählbaren Port lauschen lässt. Der verwendete Port wird dann zum Server geleitet und dieser prüft dann ob eine Kommunikation über diesen Port möglich ist.

Weil das ganze ja sowieso durch den Server gemanaged wird, spielt es für die Clienten keine Rolle wer nun nen TcpServer am laufen hat, einer reicht ja.

Sonst kennt ihr keine Alternative um sicherzustellen das ein Port durchgeroutet wird?

Gruß
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Ich hätte sonst noch ein Stichwort welches "UPnP" lautet
meinst du Universal Plug and Play ?
Der verwendete Port wird dann zum Server geleitet und dieser prüft dann ob eine Kommunikation über diesen Port möglich ist.
Du baust ne verbindung zu dem server auf ...
danach danach kannd er client dem Server die info schicken, dass er am port XYZ nen Serversocket lasuchen laesst. Nun versucht der server eine verbindung zum client auf den port aufzubauen. Kommt diese verbindung zustande, (und schickt der client eine vorher "abgemachte(verschluesselte) antwort, um IP Spoofing zu vermeiden) kannst sicher sein das der Client direkt verbindung faehig ist ... egal ob er ohne router am inet iss oder hinter dem router iss aber die "richtigen" ports forwarded.
spielt es für die Clienten keine Rolle wer nun nen TcpServer am laufen hat, einer reicht ja.
Die hohe schule waer naetuerlich, 100% dezentrale verwaltungsserver (es konnen alles clients die p2p faehig sind diesen job uebernehmen), die selber die vermittlungsserver listen verwalten und den clients zukommen lassen.
Dann brauchst nur noch einen zentralen server, der bei der initialisierung eines clients nur ne liste von probebaren vermittlungsservern rausgibt. die werden vom client dann ange"pingt" bekommen aktueller verwaltungslisten und geben diese listen auch weiter ... so dass deine clients nie weider deinen zentralen server brauchen.

Skype macht eigentlich genau das was du willst, da hat upsala scho recht. Das iss aber kein netzwerktechnisches Problem, sondern ein logistisches, weil es was mit Netzwerk (ohne technik) im sinne von Vernetzung zu tun hat.

Schau dir paar kapitel zum thema "onion routing" an, dann stell dir das ganze vor mit noch weniger zentralisiertern verwaltungsservern sondern das die clients in der Lage sind, alle verwaltungstaetigkeiten zu uebernehmen. Und das auch tun, (bei skype hat man ne generalzustimmung gegeben).

Ciao ...
Antworten