Chat in C++?



  • Hi! Ist es möglich einen Chat zu programmieren, der komplett ohne Server oder so läuft? Also ich meine, dass einfach 2 leute machen das programm auf, der iene gibt was ein und das sendets dann an den jeweils andern...
    Gibts tutorials dazu?
    (Hab mich bisher noch net mit Internet usw. in C++ befasst)

    mfg Finn



  • Ja ist möglich.
    Tutorials darfst du selber suchen. Eine Möglichkeit wäre nach Sockets zu schaun.


  • Administrator

    Nein ist nicht möglich. Irgendjemand muss grundsätzlich einen Server eröffnen. Das kann aber auch einer der beiden Chatter sein. Dann kann der andere sich zur entsprechenden IP verbinden.
    Heutzutage, wo viele Leute Router haben, ist das allerdings ein wenig problematisch, da die Verbindung nicht durch die Firewall kommt. Man müsste also den Port öffnen und die Pakete an die eigene IP im internen Netzwerk weiterschicken, damit dies funktioniert.

    Ein gutes C Tutorial, welches mit den Sockets der WinAPI arbeitet, findest du hier:
    http://www.c-worker.ch/tuts.php

    Wenn du dich da mal gefestigt hast und dich sonst noch ein wenig durch die Begriffe in Wikipedia gelesen hast, dann kannst du dir vielleicht mal Boost.Asio anschauen:
    http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio.html

    Grüssli & viel Glück 🙂



  • Ist es nicht so, dass wenn man ein Paket zB. über port 12345 verschickt, man dann über diesen Port automatisch empfangen kann (Router)? Oder ist das dieses uPnP?

    Ich meine, mich zu erinnern, dass ich mal über einen Port empfangen konnte, nachdem ich über ihn etwas gesendet habe (Eigenes Programm), obwohl mein Router eigentlich nix reinlässt (Außer default virtual server settings wie FTP/HTTP/...)

    😕


  • Administrator

    Wenn du bereits etwas verschickt hast, unter gewissen Bedingungen ja, aber ansonsten, nein. Sonst könnte man schliesslich gar nicht über den Router hinaus kommunizieren, da jeder Antwort von der Firewall verschluckt werden würde.
    Eine TCP Verbindung braucht allerdings einen vollständig durchgeführten Handschlag, um die Kommunikation aufzunehmen. Zwischen zwei Computern, welche hinter einer voll aktiven Firewall stehen, ist dies nicht möglich.

    Bei UDP gibt es Möglichkeiten die Firewall zu umgehen, meistens braucht es dazu allerdings einen dritten Server, welcher die beiden Clients zusammenbindet. Skype macht dies zum Beispiel so. Hier gibt es einen Artikel dazu:
    http://www.h-online.com/security/How-Skype-Co-get-round-firewalls--/features/82481

    Grüssli



  • also ich wills in c++ machen...und wenn man vorher die firewall ausschaltet?


  • Administrator

    Finn schrieb:

    also ich wills in c++ machen...und wenn man vorher die firewall ausschaltet?

    Mit reinem C++ kannst du es sowieso nicht machen, denn Standard C++ kennt kein Netzwerk oder ähnliches. Du musst auf das Betriebsystem zurückgreifen und diese Schnittstellen sind meistens in C geschrieben. Deshalb sind auch die meisten vollständigen Tutorials in C. Boost.Asio ist ein sehr schöner C++ Wrapper für die unterschiedlichen C Schnittstellen der Betriebsysteme, leider muss man bereits Wissen mitbringen, um Boost.Asio verwenden zu können.

    Und klar kannst du die Firewall abstellen. Das ändert aber an der C oder C++ Tatsache nichts. Zudem bringt es dir nichts, da niemand freiwillig für dein Programm die Firewall abstellen wird. Du musst lernen so zu programmieren, dass es mit der Firewall geht.
    Für reine Tests kannst du allerdings über den Localhost (127.0.0.1) gehen. Also die Pakete verlassen deinen Computer gar nie, sondern du schickst sie an dich selbst. Sowas lernst du aber auch im Tutorial 😉

    Grüssli



  • oh wenn die meisten os-funktionen in c sind, kann man die natürlich nicht mit c++ benutzen oder in klassen packen. mist 🙄



  • noch mal zum thema firewall:

    du kannst nicht nur 2 reine clients sich verbinden lassen...
    du brauchst einen, der die verbindung öffnet (der andere braucht dann die ip, das muss man z.bsp. lösen, indem du ne url hast. (geht natürlich auch lokal und mit dyn-dns)
    die seite dahinter muss dann die möglichkeit bieten, abzufragen, ob ein server da ist und wenn ja, welche ip der hat.
    der server wiederrum muss der website dann wieder was senden, dass er jz ein server ist.
    das problem auf der serverseite ist jetzt der router - dort muss der jeweilige port freigeschalten sein.
    dann gibt es (evtl) noch ne richtige (software-)firewall - die wird dann nachfragen, ob der port wirklich geöffnet werden soll oder so in etwa - das kann man auch nicht so einfach umgehen (sonst wärs ja sinnlos 😉 ).
    dann, wenn du einmal verbunden bist, kann dir das alles egal sein, weil die verbindung ja bestehen bleibt...

    bb

    PS: Es gibt auch Verfahren, wo man den Router-Port nicht freigeben muss - so ne Technik nutzt z.Bsp. Skype - mir fällt aber der Name gerad nicht ein 😃
    funktioniert in etwa so, dass die beiden fast gleichzeitig auf den jeweils anderen verbinden, wenn mich nich alles täuscht - wird aber nicht gerade einfach zu implementieren sein ^^


  • Administrator

    dgrat schrieb:

    oh wenn die meisten os-funktionen in c sind, kann man die natürlich nicht mit c++ benutzen oder in klassen packen. mist 🙄

    Wer hat das gesagt? Wenn du meinst, dass ich das war, dann solltest du meine Beiträge nochmals lesen. Du durchmischst meine Aussagen.

    unskilled schrieb:

    du brauchst einen, der die verbindung öffnet (der andere braucht dann die ip, das muss man z.bsp. lösen, indem du ne url hast. (geht natürlich auch lokal und mit dyn-dns)

    Wie bitte? Für eine IP braucht man nicht zwingend eine URL. Oder willst du mit diesem seltsamen Satz sagen, dass man, wenn man eine URL hat, diese zuerst in eine IP auflösen muss? 😕

    unskilled schrieb:

    die seite dahinter muss dann die möglichkeit bieten, abzufragen, ob ein server da ist und wenn ja, welche ip der hat.

    Welche Seite dahinter? Was verstehst du hier unter Seite? Wieso soll eine Seite abfragen? Meinst du den Client? Der muss nicht zuerst nach einem Server fragen, sondern mit der IP probieren die Verbindung herzustellen, sofern wir ein verbindungorientiertes Protokoll verwenden. Bei UDP muss keine Verbindung hergestellt werden, da es gar nicht möglich ist.

    unskilled schrieb:

    der server wiederrum muss der website dann wieder was senden, dass er jz ein server ist.

    Was? Der Server muss der Website was senden? Wie soll man das verstehen? 😕
    Bei HTTP, was ja nicht gerade etwas mit einem Chat zu tun hat, kommt die Website meistens vom Server. Der Server sendet nicht etwas an die Website, sondern er sendet die Website an den Client.

    unskilled schrieb:

    das problem auf der serverseite ist jetzt der router - dort muss der jeweilige port freigeschalten sein.

    Gut, ja, das stimmt. Der Server muss entsprechenden Ports in der Firewall öffnen, dadurch wird der Firewall mitgeteilt, das ankommende Pakete auf dem entsprechenden Port weitergereicht und nicht verbrannt werden.

    unskilled schrieb:

    dann, wenn du einmal verbunden bist, kann dir das alles egal sein, weil die verbindung ja bestehen bleibt...

    Nur bei einem verbindungsorientierten Protokoll. Aber auch sonst, sollte dir nicht alles egal. Die Verbindung kann abbrechen, Pakete können verloren gehen und es gibt zum Teil Firewalls, welche auch noch den Inhalte überprüfen, was übermittelt wird und einzelne Inhalte blockieren. usw. usf.

    unskilled schrieb:

    PS: Es gibt auch Verfahren, wo man den Router-Port nicht freigeben muss - so ne Technik nutzt z.Bsp. Skype - mir fällt aber der Name gerad nicht ein 😃
    funktioniert in etwa so, dass die beiden fast gleichzeitig auf den jeweils anderen verbinden, wenn mich nich alles täuscht - wird aber nicht gerade einfach zu implementieren sein ^^

    [] Du hast den Thread gelesen.
    [] Du hast das Verfahren verstanden.

    😉

    Grüssli



  • Die Seite braucht man logischerweise, weil man wohl nicht jedes mal erst die IP herausbekommen will, die der andere, mit dem man dann schreiben will, wohl gerade hat...

    gibt auch andere wege hierfür(z.bsp. das beide sich bei dyn-dns anmelden) - aber keine, die das problem mit dem server auch gleich beheben...
    es ist einfach ein nicht triviales problem, wenn es 2 gleiche programme geben soll und jeder die möglichkeit haben soll, den anderen anzuschreiben...
    vll hast du ja ne einfacherer möglichkeit, das zu bewerkstelligen... not!

    Bei HTTP, was ja nicht gerade etwas mit einem Chat zu tun hat, kommt die Website meistens vom Server. Der Server sendet nicht etwas an die Website, sondern er sendet die Website an den Client.

    Nachdem man ne Anfrage geschickt hat...
    Hier muss man in der Anfrage dann halt signalisieren, dass man jz der Server ist...

    bb

    PS:


    [] Ich hab das Verfahren verstanden.

    das liegt allerdings daran, dass es mir damals(und auch immernoch) egal war, wie genau das funktioniert...


  • Administrator

    Also ganz ehrlich, ich weiss immer noch nicht, was du sagen willst. Ich weiss nicht, was du unter Seite verstehst und in welchem Zusammenhang du dies mit dem Thread setzt. Es gibt Duzende von Möglichkeiten, wie man eine IP austauschen kann, bzw. die IP des anderen herausfinden. Das kommt ganz darauf an, wie man sein Programm aufbaut oder was es können soll.
    Aber trotzdem, wie passt dies in den Thread? Und was genau meinst du? Was willst du ausdrücken?

    Auch das mit dem HTTP, so wie ich es mir aktuell irgendwie zusammenreimen kann aus deinen Aussagen, wäre es einfach komplett verkehrt. Also entweder weisst du nicht wovon du sprichst oder aber, und das ist meine Annahme, du drückst dich nicht richtig aus. Ich verstehe jedenfalls nicht richtig, was du sagen willst. Ich kann es mit meinem Wissen aus Netzwerk und co nicht verknüpfen.

    Zum PS:
    Du hast auch das hier gelesen?

    Dravere schrieb:

    ...
    Bei UDP gibt es Möglichkeiten die Firewall zu umgehen, meistens braucht es dazu allerdings einen dritten Server, welcher die beiden Clients zusammenbindet. Skype macht dies zum Beispiel so. Hier gibt es einen Artikel dazu:
    http://www.h-online.com/security/How-Skype-Co-get-round-firewalls--/features/82481

    Wieso erwähnst du es dann nochmals und dann auch noch in einer so verwirrenden Form? 🙂

    Grüssli



  • Also inwischen versteh ich einfach grad nimmer worüber ihr redet...sprich ich lasses wohl erstmal und lern noch weiter 😛



  • Ich erkläre es gerne noch mal auf Deutsch:

    Aaaalso:
    Gegeben:
    Computer 1
    Computer 2
    Server

    Gesucht:
    Verbindung von Computer 2 an C1. (Anruf oder andere Peer-to-Peer-Anwendungen wie Chats)

    Lösung:

    Computer 1 und 2 müssen sich auf einem Server registrieren. Das machen sie mit dem TCP-Protokoll über Port 80, der wegen HTTP sowieso immer offen ist und ein Handshake damit möglich wird. Der Server erfährt nun schon mal die IPs von Computer 1 und 2. Der Server sendet nun ein paar Test-Requests an Computer 2, um herauszubekommen, welchen Kommunikationsport C2 benutzen kann/will, um Daten zu senden. Wenn der Server den nun auch hat, schickt er IP und Port an C1. C1 kann nun starten, C2 zu kontaktieren. Also macht C1 einen UDP-Request an C2, z.B. an IP 99.999.999 Port 6666. Wenn der UDP-Request von C1 an C2 startet, haut dieser ein temporäres Loch ( = der Lieblings-Port von C1, z.B. 5555) in die eigene Firewall und der Request geht zu C2. Aber der Port 6666 von der Firewall von C2 ist geschlossen, der Request scheitert. 😞
    UDP ist das egal, während bei TCP eine Antwort ( =Shakehands) kommen muss, ist das bei UDP nicht notwendig. Aber diese Aktion hat 2 dolle Sachen gemacht: a) ein Loch in der Firewall von C1, was er sich selber durch seinen fehlgeschlagenen Request reingedonnert hat und b) C1 akzeptiert jetzt durch den Request alle Anfragen von C2 ( =99.999.999:6666) als Antwort, C1 ist jetzt offen für C2.
    Jetzt ist der Server wieder dran: er schickt die Daten von C1 an C2 (IP und Port, z.B. IP 11.111.111 und der Port, wie oben, 5555). C2 macht jetzt auch einen UDP an 11.111.111:5555, haut sich auch ein Loch in die eigene Firewall und geht zum Loch 99.999.999:6666, er kann da durch, weil C1 denkt, dass C2 antwortet, da C1 ja einen UDP-Request an C2 gesendet hat. Jetzt haben beide ein Loch, beide haben Kontakt und der Server kann gehen. 🙂

    Mal es dir nach meiner Beschreibung ruhig auf, wenn du es noch nicht verstanden haben solltest. 😉



  • Ah k also das is mal ne verdammt gute Erklärung!Habs verstanden.Aber ich glaube fast an der Umsetung wirds scheitern...was muss ich mir denn für tutorials dafür angucken oda was muss ich googlen?
    Vielen Dank schonmal für die gute Erklärung!



  • Das sind einfach nur Sockets, ich habe es aus "C++ von A bis Z", aber es gibt auch Tuts: In Deutsch

    Was mich mal interessieren würde ist, wie man Audiodaten über UDP streamen kann. 🙂



  • Dann werd ich mich da mal durchfressen ^^
    Danke 🙂



  • @Dravere:
    OK - das PS iwo hab ich nich gesehen ^^

    ein letzter versuch noch ^^
    "der komplett ohne Server oder so läuft" (jedenfalls hab ich noch nirgendwo gesehen, dass der TO sich umentschieden hat)
    heißt, dass es nur irgendwo n (n=2!?) clients gibt.

    da man aber den server braucht, kann man als günstigen und einfachen ersatz eine Website dazu "missbrauchen".
    das er gebraucht wird, sollte ja offensichtlich sein!?
    dann kann man eben direkt beim starten nen http-request dort hinsenden. daraufhin erhält man die information, ob schon ein server läuft und ggf. die server-ip.
    wenn noch kein server läuft, muss der client, der das request absendet, der server sein.

    so meinte ich das - und fand den ansatz eigtl recht elegant als ich es damals ma iwo gesehen hatte. nachteil erkenn ich auch keinen, da man nur ne domain (gibts ja genug möglichkeiten, eine kostenlos zu bekommen) braucht. dazu brauch man dann halt noch ca. 5KB Webspace - und daran sollte es nun auch nicht hängen 😉

    bb



  • Und einen Webspace, der CGI-C++-Codes akzeptiert. HAHA das kostet. 🙄



  • unskilled schrieb:

    das er gebraucht wird, sollte ja offensichtlich sein!?

    Das kommt darauf an ...
    und zwar darauf, ob ich nur ein bißchen mit meinen Freunden chatten will, oder ob es etwas 'professionelleres' sein soll.

    Im ersten Fall mach ich einfach einen ServerSocket, maile meinen Kumpels meine IP, und ab geht's (vorher forwarde ich noch den entsprechenden Port in meiner Firewall).
    PS Ich habe gehört, daß, wenn man INet über einen Unitymedia - Kabelanschluß betreibt, man immer die gleiche (eine feste) IP hat. Falls das stimmt, macht das die Sache noch einfacher.



  • Ad aCTa schrieb:

    Und einen Webspace, der CGI-C++-Codes akzeptiert. HAHA das kostet. 🙄

    dir ist klar, was ich mit website und php meine?

    ip bei kabel:
    naja - ich hab zwar lange zeit immer ne gleiche ip(auf jeden fall >24h), aber imho ist nicht garantiert, dass ich immer die selbe behalte...
    wenn es wirklich nur so sein soll, dann www.dyndns.com
    viele router können das auch direkt updaten, da muss man dann kein komisches programm laufen lassen ^^

    bb


Anmelden zum Antworten