[WinSockets] Verbindungsproblem via TCP/IP



  • Schönen guten Abend allerseits 😉 !

    Folgendes Szenario/Problem:
    Ich möchte 2 Computer über's Internet nach dem Server/Client-Prinzip (also via WinSockets) kommunizieren lassen. Dabei existiert auf beiden keine Firewall oder ähnliches. Auf dem einen PC läuft der Server und wartet auf Verbindungen (listen-Funktion), auf dem anderen PC wird dann der Client gestartet, der sich mit dem Server verbinden *soll*, das tut er aber nicht 🙄 . Die Ziel-IP (des Servers) für den Client hole ich mir über http://meineip.de , als Port habe ich verschiedenes probiert (80, 82, 1024, 3306). Über WSAGetLastError bekomme ich nach dem Aufruf von 'connect' (beim Client) den Fehlercode 10051 (WSAENETUNREACH), was bedeutet:

    MSDN, WSA-Error-Codes => http://msdn2.microsoft.com/en-us/library/ms740668.aspx schrieb:

    Network is unreachable.
    A socket operation was attempted to an unreachable network. This usually means the local software knows no route to reach the remote host.

    Der Server bekommt übrigens von den Verbindungsversuchen des Clients scheinbar nichts mit (beim erfolgreichen Aufbau einer Verbindung sollte er dies nämlich anzeigen).

    Über Port 82 hat es in meinem lokalen Netzwerk bereits funktioniert, aber im Internet geht es nicht.

    Vllt. fällt einem dazu ja was ein 💡 . Falls mehr Informationen bzw. Quellcode benötigt werden, einfach melden, die/der wird dann sofort nachgeliefert 😉 .

    Schonmal vielen dank & viele Grüße 👍

    PS: In meinen Testszenarien waren beide PC's über einen Router mit dem Internet verbunden, ist evtl. noch relevant 😉 .



  • #1) du musst den Port im Router vom Server-PC freischalten, sonst kann es nicht gehen.
    #2) WSAENETUNREACH wundert mich in dem Fall, das würde ich erwarten wenn ... man z.B. 10.0.0.1 oder sowas als destination IP angibt, oder der Client PC keine Internetverbindung hat.



  • Erstmal danke für Deine (schnelle) Antwort 👍 !

    zu 1: Der ist freigegeben^^, hatte auch schon dran gedacht, aber daran liegts nicht 🙄 - sorry hätte ich schreiben müssen.
    Und zu 2: Jupp, hab mich auch gewundert. Wenn der Server am anderen Ende nicht läuft, gibts n TimeOut-Error.

    Weitere Ideen 🕶 ?



  • Es gibt auch Router, die das so nicht unterstützen.
    Habe z.B. auch so einen, einen 500W...

    Kann mich in diesem Fall auch nicht selber über dyndns erreichen .



  • Verwenden beide PCs gleiche Router (Hersteller/Modell)?
    Du könntest mal versuchen Client und Server zu vertauschen, vielleicht liegts ja wirklich an einem der beiden Router.

    Und versuch mal ne andere Portnummer, irgendwas > 1024, sagen wir 22000 oder sowas.



  • xyz123 schrieb:

    Es gibt auch Router, die das so nicht unterstützen.
    Habe z.B. auch so einen, einen 500W...

    Kann mich in diesem Fall auch nicht selber über dyndns erreichen .

    Hm ich hab n D-Link Router... . Aber habe es schon, wie hustbaer vorgeschlagen hat, andersherum probiert und es hat auch nicht geklappt.

    hustbaer schrieb:

    Verwenden beide PCs gleiche Router (Hersteller/Modell)?

    Ne, meiner ist (siehe oben) von D-LINK, der ander von der Telekom (T-Sinus...).

    hustbaer schrieb:

    Du könntest mal versuchen Client und Server zu vertauschen, vielleicht liegts ja wirklich an einem der beiden Router.

    Joar, habe ich gemacht, funktioniert auch nicht.

    hustbaer schrieb:

    Und versuch mal ne andere Portnummer, irgendwas > 1024, sagen wir 22000 oder sowas.

    Jupp, auch probiert (mit Port 22000), im LAN gehts, im I-Net nicht 😞 .

    Hier mal die Ausgabe des Servers, bzw. des Clienten (vllt. hilft das ja noch):

    Server-Log schrieb:

    Please enter the port-number (Default 22000): ok
    Server Socket successfuly created!
    Server-Socket binded on local port 22000!
    Server is in the Listening-Mode (1 client maximum!)...

    Client-Log schrieb:

    Please enter the port-number ("ok" means default port 22000): ok
    Please enter the ip-address ("ok" means default local-ip 169.254.21.54): 217.236.73.195
    Client-Socket successfuly created!
    Error in method 'Connect': Connection buildup failed. Check the WSA-Error-Code for more information! WSA-Error-Code: 10060

    Allerdings handelt es sich jetzt (wie man sieht :p ) um den Error Code 10060 (WSAETIMEDOUT) 🙄 . Dazu die MSDN:

    MSDN, WSA-Error-Codes => http://msdn2.microsoft.com/en-us/library/ms740668.aspx schrieb:

    Connection timed out.
    A connection attempt failed because the connected party did not properly respond after a period of time, or the established connection failed because the connected host has failed to respond.

    PS: Wie gesagt, falls ich Code posten soll ➡ kein Problem! Allerdings ist es nicht so einfach den zu reduzieren, da alles in einer Klasse gekapselt ist.

    Danke nochmal für Eure Antworten!



  • Noch ne Ergänzung:
    Wenn ich versuche, den Ziel-PC, auf dem der Server läuft, anzupingen, funktioniert das nicht. Andersherum funktioniert das allerdings 😮 . Das Programm funktioniert aber trotzdem nicht (in beiden Richtungen).



  • Auf welche IP bindest du den Server-Socket denn?



  • Also ich hab' nen D-LINK DI 604, und mit dem geht sowas problemlos.

    Den Client kannst du mal testen indem du als IP einfach www.google.com oder sowas angibst (wenn dein Client keine URLs über DNS auflösen kann hol dir halt vorher die IP von www.google.com mit ping oder sowas, und gib dann die IP ein).
    Als Port gibst du 80 an, wenn das geht, dann funktioniert der Client schonmal (bis zu dem Punkt wo die Verbindung aufgebaut ist).

    Den Server kannst du testen indem du ihn lokal laufen lässt, und dann mit "telnet lokale-ip port" versuchst draufzuconnecten (als "lokale-ip" auf jeden Fall NICHT die 127.0.0.1 nehmen, sondern die "echte" lokale IP).

    Ahja, dass sich der Ziel PC nicht anpingen lässt liegt wohl wahrscheinlich an dessen Router.
    Bist du auch sicher dass du im Router vom Server PC den Port richtig freigeschaltet hast?



  • geeky schrieb:

    Auf welche IP bindest du den Server-Socket denn?

    Öhm, wieso ne IP binden? Meinst Du den Port? Sonst verstehe ich Deine Frage nicht 🙄 .

    hustbaer schrieb:

    Also ich hab' nen D-LINK DI 604, und mit dem geht sowas problemlos.

    Hm ich hab den D-LINK DI 624+ 😃 .

    hustbaer schrieb:

    Den Client kannst du mal testen indem du als IP einfach www.google.com oder sowas angibst (wenn dein Client keine URLs über DNS auflösen kann hol dir halt vorher die IP von www.google.com mit ping oder sowas, und gib dann die IP ein).
    Als Port gibst du 80 an, wenn das geht, dann funktioniert der Client schonmal (bis zu dem Punkt wo die Verbindung aufgebaut ist).

    Jupp, hatte ich bereits vorher gemacht. Er kann auch die URL auflösen. Hab das sowohl mit Google-IP, also auch mit der Google-URL getestet, funktioniert beides. Das Ergebnis (für die URL) sieht dann so aus:

    Client-Log schrieb:

    Please enter the port-number ("ok" means default port 22000): 80
    Please enter the ip-address ("ok" means default www.google.de): ok
    Client-Socket successfuly created!
    Client connected via Port 80 with www.google.de!
    Server-Command (maximum 256 signs):

    hustbaer schrieb:

    Den Server kannst du testen indem du ihn lokal laufen lässt, und dann mit "telnet lokale-ip port" versuchst draufzuconnecten (als "lokale-ip" auf jeden Fall NICHT die 127.0.0.1 nehmen, sondern die "echte" lokale IP).

    Ohja, gute Idee, danke für den Tipp! Aber das Ergebnis ist -glaube ich- nicht sehr informativ:

    Server-Log schrieb:

    Please enter the port-number (Default 22000): ok
    Server Socket successfuly created!
    Server-Socket binded on local port 22000!
    Server is in the Listening-Mode (1 client maximum!)...
    New connection successfuly accepted!
    Waiting for commands...

    ➡ Der Server funktioniert also auch.

    hustbaer schrieb:

    Ahja, dass sich der Ziel PC nicht anpingen lässt liegt wohl wahrscheinlich an dessen Router.
    Bist du auch sicher dass du im Router vom Server PC den Port richtig freigeschaltet hast?

    Hm, jupp, da bin ich mir zu 99% sicher 😉 . Es ist leider nicht mein PC, sondern der eines Freundes. Ich hab übrigens nochmal bei mir nachgeguckt und meine Firewall (im Router) müsste sogar deaktiviert sein, hier mal ein Screenshot:
    ➡ http://img249.imageshack.us/my.php?image=firewallconfigmenuhz7.jpg

    Obwohl...wenn ich so drüber gucke und unten das "Deny" sehe, bin ich mir mittlerweile selbst nicht mehr sicher 😃 .



  • Öhm, wieso ne IP binden? Meinst Du den Port? Sonst verstehe ich Deine Frage nicht

    Du musst deinen socket mit "bind" an eine IP + Port binden befor du den an listen übergeben kannst.
    Auf einem normalen System stehen mindestens 2 IPs zur Verfügung auf die man Sockets binden kann, nämlich die loopback Adresse (127.0.0.1) und die lokale IP der Netzwerkkarte. Man kann allerdings auch mehrere IPs verwenden, sogar mehrere mit ein und der selben Netzwerkkarte.

    Daher muss man bei bind eine IP mit angeben.

    ----

    Zu deinem Screenshot: die Sektion vergiss mal, da stellst du am besten garnix drin rum. Interessant ist die Sektion "Virtual Server", dort musst du den Port für den Server zu deinem PC "durchpatchen".
    Alle PCs hinter dem Router haben ja schliesslich nur eine sog. "public IP" nach aussen hin (zum Internet), intern aber verschiedene. Wenn nun vom Internet auf diese eine "public IP" eine Connection auf Port 22000 daherkommt, woher soll dann dein Router wissen dass er die Verbindung an deinen PC weiterleiten soll? Kann er nicht wissen, es könnte ja zig oder hunderte PCs hintern dem Router geben.

    Und genau das teilst du ihm in der Sektion "virtual server" mit.

    Wenn die Maske bei deinem DLINK gleich wie bei meinem ist, dann musst du da inetwa folgendes eintragen:

    [x] enabled   [ ] disabled 
    Private IP      [<die interne IP deines PCs>]
    Protocol Type   [TCP]
    Private Port    [22000]
    Public Port     [22000]
    Schedule
                    [x] always
                    ...
    

    Private Port müssen dabei nicht notwändigerweise gleich sein, aber um Verwirrung zu vermeiden würde ich es empfehlen.

    Mit "private" ist immer das Netzwerksegment "hinter" deinem Router gemeint (also das wo dein PC drin steht), und mit "public" ist das Internet gemeint, bzw. das was du am "Internet" Anschluss des Routers hängen hast.

    p.S.: wenn du bei "virtual server" Einträge machst werden automatisch auch dazugehörige Einträge bei "firewall" auftauchen. Die sind gut und nötig, sonst geht nix, also wie gesagt, lass die "firewall" Seite einfach in ruhe 🙂



  • hustbaer schrieb:

    Du musst deinen socket mit "bind" an eine IP + Port binden befor du den an listen übergeben kannst. Daher muss man bei bind eine IP mit angeben.

    Achja klar, das habe ich mit INADDR_ANY gelößt, id est:

    void CWinTcpSocket::Bind(USHORT usLocalPort)
    	{
    		if(m_hSocket == INVALID_SOCKET)
    			throw CBadSocket(TEXT("Error in method 'Bind': The socket must have been created previously."), 0);
    
    		SOCKADDR_IN siAddr;
    
    		siAddr.sin_addr.s_addr  = INADDR_ANY;
    		siAddr.sin_family       = AF_INET;
    		siAddr.sin_port         = htons(usLocalPort);
    		memset(siAddr.sin_zero, 0, sizeof(siAddr.sin_zero));
    
    		if(bind(m_hSocket, reinterpret_cast<const SOCKADDR*>(&siAddr), sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
    			throw CBindingFailed(TEXT("Error in method 'Bind': Port-Binding failed. Check the WSA-Error-Code for more information!"),
    								 usLocalPort, WSAGetLastError());
    	}
    

    Oder ist das nicht empfehlenswert?

    Hm, perfekt! Habe jetzt die Einstellungen unter Virtual Server gemacht und es funktioniert, also falls ich den Server starte (und der Client 'auf mich' connected). Andersherum nicht, aber das wird dann an der entsprechenden Einstellung im anderen Router liegen.
    Was eine Arbeit nur für 'ne kleine Server-Client-Verbindung 🙄 .

    In jedem Fall: vielen Dank an alle 👍 ! - Problem gelößt!


Anmelden zum Antworten