Client mit Server verbinden übers Internet (Ipadressen problem)
-
Hi Leute ,
ich bin neu hier und wollte gleich mal ne frage stellen ...
Undzwar habe ich einen eigenden Server kreiert mit dem sich Clients verbinden können mit TCP sockets
Mein problem ist das ich das übers Internet laufen lassen will , local funktioniert alles und über lan auch .und da weiß ich nicht wie das geht . ich mochte es nur gerne über meinen PC laufen lassen , den aber auch mal ausstellen
Das Programm läuft super ohne probleme aber ich muss im Client immer die IP adresse meines Computers(oder was auch immer angeben)deswegen brauche ich eine feste IPadresse (auch wenn ich den Pc neu starte)
oder irgentwas andres ...also um es kurz zu machen :
ich brauche eine möglichkeit das sich mein client übers inet mit meinen server sich verbindet ohne geld auszugebenich habe echt keine ahnung wie das so läuft mit ipadressen undsoweiter ...
und muss ich im router die ports freischlaten für mein Server?
deswegen sagt mir dazu alles was ihr wisst ^^
Dankemvg Tibolus
-
Welche IP verändert sich? Die interne im LAN? Dann konfigurier dein LAN entsprechend um. Die öffentliche Adresse die ein ISP an dein Modem/Router/PC/WasAuchImmer vergibt? Da du kein Geld ausgeben möchtest, bleiben dir noch so Dienste wie dynDNS, die sind für Privatpersonen soweit ich weiß gratis. Außerdem wirst du, falls du hinter einem Router sitzt, dafür sorgen müssen, dass die Ports richtig weitergeleitet werden. Das zu Beschreiben ist ein kleines Buch für sich, erst einmal solltest du die beiden Fragen oben klären.
-
Ich würde mal sagen, da gibt es grob zwei Möglichkeiten. Erstens:
- DynDNS Account erstellen
- DynDNS Account im Router eintragen
- Die entsprechenden Ports im Router öffnen und an deinen Rechner weiterleitenstruct sockaddr_in addr = {0}; struct hostent *host; const char *hostname = "xxx.dyndns.org"; host = gethostbyname(hostname); if (!host) // .. fail addr.sin_addr = *(struct in_addr*)host->h_addr;
Zweitens:
Einen VServer für ~2-5€/Monatl. mieten und den Server darauf laufen lassen. Dein Rechner verbindet sich dann auf den Server und ist von außen erreichbar.---
Egal für was du dich entscheidest, du solltest aufpassen, dass bei deinem Server kein Stackoverflow oder solche Scherze möglich sind, man weiß ja nie.
-
danke erstmal cooky und SeppJ ... den tipp werde ich gleich mal ausprobieren ^^ und nein der user weiß nichtmal das er sich mit meinen pc verbindet
da er nur zählt wie oft mein programm geused wird ^^
-
so ich habe nun einen acc dort gemacht
XXX.dyndns-ip.com
mein siemens router hat auch alles angenommen ...
"Update successful ! (But IP no change since last update)"die c++ stelle sieht bei mir eher so aus
memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(8896); addr.sin_addr.s_addr=inet_addr("XXX.dyndns-ip.com"); //oder was muss hierhin? rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
so verbindet der sich der clinet aber immernochnicht ...
müssen die Ports unter
Port Forwarding oder
Port Triggering ??und wie leite ich die ports weiter ...
sorry aber bei google ist nichtviel unterstüzung bei siemens routern
muss ich nur den Port 8896 mit TCP freischalten ? oder sonst noch was ?
und wie weiß DynDNS immer meine neue ip adresse (oder macht das der router)
-
Tibolus schrieb:
Port Forwarding
Sollte funktionieren.
Tibolus schrieb:
Port 8896 mit TCP freischalten?
Wenn du nur diesen Port nutzt, ja.
Tibolus schrieb:
und wie weiß DynDNS immer meine neue ip adresse (oder macht das der router)
Das sollte der Router machen.
Zu dem Code: inet_addr() wandelt nur Strings zu Zahlen um, aber löst eben keine Hostnamen auf. Da ich ja schon geahnt habe, dass die Frage kommen wird: Siehe meinen Beitrag oben! Da steht bereits fertiger Code, der dir den Hostnamen auflöst.
Und im übrigen finde ich es ein Unding, ein Programm irgendwo hin zu verbinden, ohne den User zu fragen. So etwas ist einfach nur nervig und hat keinen Stil. Mach wenigstens eine Anfrage "Möchtest du dem Programmierer hinter dem Tool Danke sagen?" "Ja/Nein".
-
Musst noch den Hostnamen auflösen, also zu einer IP-Adresse umwandeln ..
long getIPAdress (char* getHost, SOCKADDR_IN* addr) { unsigned long ip; HOSTENT* he; if (getHost == NULL || addr == NULL) return SOCKET_ERROR; ip = inet_addr (getHost); if (ip != INADDR_NONE) addr->sin_addr.s_addr = ip; else { he = gethostbyname (getHost); if (he == NULL) return SOCKET_ERROR; else memcpy (&(addr->sin_addr), he->h_addr_list[0], 4); } return 0; } [...] memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(8896); if (getIPAdress ("xxx.dyndns-ip.com", &addr) == SOCKET_ERROR) { // Hat wohl nicht ganz geklappt } rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
Zum Rest will ich dir nichts sagen, weil ich gemein bin
Naja, eigentlich weiß ichs einfach nicht zu 100% ^^EDIT: cooky war schneller, ich geh nach hause .. ^^
meinen code kannste dann ja auch mehr oder weniger knicken, wurde ja auch schon weiter oben gepostet
-
also wie muss ich das jetzt darein machen ^^
das ist meine Komplette client source
#include <winsock2.h> #include <Windows.h> #include <stdio.h> #include <iostream> using namespace std; #pragma comment( lib, "ws2_32.lib" ) //Prototypen int startWinsock(void); int main() { char Daten[1024]; // Sleep(10000); long rc; SOCKET s; SOCKADDR_IN addr; char buf[1024]; rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } s=socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } // Verbinden memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(8896); addr.sin_addr.s_addr=inet_addr("XXX"); rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Verbunden mit Tibolus-Server\n"); } Sleep(500); closesocket(s); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }
Die funktionen hab ich jetzt rausgenommen
Aber wie muss ich da jetzt
XXX.dyndns-ip.com
reinbekommen ...THX wenn ihr mir das sagen könntet ^^
Bin erst vor 2 tagen mit der netzwer programmierung angefangen und kann nochnicht viel damit ^^
-
#include <stdio.h> #include <Winsock2.h> #pragma comment (lib, "Ws2_32.lib") int main() { const char *hostname = "xxx.dyndns.org"; char buf[1024]; SOCKET sock; SOCKADDR_IN addr = {0}; WSADATA wsadata; HOSTENT *host; if (WSAStartup(WINSOCK_VERSION, &wsadata) != 0) { fprintf(stderr, "WSAStartup() failed.\n"); return -1; } if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { fprintf(stderr, "socket() failed with: %d.\n", WSAGetLastError()); return -2; } if (!(host = gethostbyname(hostname))) { fprintf(stderr, "Could not find hostname: %s", hostname); return -3; } addr.sin_addr = *(struct in_addr*)host->h_addr; addr.sin_family = AF_INET; addr.sin_port = htons(8896); if (connect(sock, (SOCKADDR*)&addr, sizeof(addr)) != 0) { fprintf(stderr, "connect() failed with: %d.\n", WSAGetLastError()); return -4; } printf("Verbunden mit Tibolus-Server\n"); Sleep(500); closesocket(sock); WSACleanup(); return 0; }
- <iostream> ist C++ und kein C.
- Wenn dein Projekt C und C++ nutzt, dann solltest du dich für jede Übersetzungseinheit (Datei) entscheiden.
- <Windows.h> war überflüssig.
- Das Makro WINSOCK_VERSION ist schöner als MAKEWORD(x, y);
- Bezeichner sollten einheitlich deutsche oder englische Namen tragen, vorzugsweise englische.
- Man muss nicht jede Kleinigkeit auf der Konsole ausgeben, das wächst sonst immer weiter. Fehlermeldungen sollten natürlich weiterhin möglichst detailliert sein.
-
#include <winsock2.h> #include <Windows.h> #include <stdio.h> #include <iostream> using namespace std; #pragma comment( lib, "ws2_32.lib" ) //Prototypen int startWinsock(void); long getIPAdress (char* getHost, SOCKADDR_IN* addr) { unsigned long ip; HOSTENT* he; if (getHost == NULL || addr == NULL) return SOCKET_ERROR; ip = inet_addr (getHost); if (ip != INADDR_NONE) addr->sin_addr.s_addr = ip; else { he = gethostbyname (getHost); if (he == NULL) return SOCKET_ERROR; else memcpy (&(addr->sin_addr), he->h_addr_list[0], 4); } return 0; } int main() { char Daten[1024]; // Sleep(10000); long rc; SOCKET s; SOCKADDR_IN addr; char buf[1024]; rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } s=socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } // Verbinden memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(8896); if (getIPAdress ("xxx.dyndns-ip.com", &addr) == SOCKET_ERROR) { printf("Fehler: Konnte Hostnamen nicht auflösen, fehler code: %d\n",WSAGetLastError()); } rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Verbunden mit Tibolus-Server\n"); } Sleep(500); closesocket(s); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }
Sollte eig. nicht so schwer sein ? Also wenn du dir das jetzt mal anguckst, müsste es dir doch hoffentlich relativ eindeutig vorkommen ?
-
@ Fake oder Echt Thx hat mir sehr geholfen ^^
@ cooky451 Schön aber ich arbeite auch damit in C++ , ich hab den rest nur in C geschrieben weil es deutlich einfacher ist und ich hab ja noch funktionen in C++
weil ich hab ja auch ein paar sachen aus der source genommen
so die source ist ready
an den ports muss ich noch arbeiten ^^ aber auch nochmal danke ^^
-
Also cooky's Tipps sind trotz allem recht nützlich, wenn auch Teils geschmackssache
Hätte ne Lib rumliegen, die viele Socketfunktionalitäten kapselt, also auch das lästige initialisieren eben, sowie natürlich auch senden/empfangen ..
Falls du Interesse hast, kann ich dir die die Tage ja mal zukommen lassen, ist auch dokumentiert und läuft ab Windows NT
-
Wenn es dir nur um Statistiken geht, dann besorg dir Webspace mit PHP-Support (gibts auch kostenlos!). Dort bastelst du dir ein PHP-Script, welches dein Programm bei jedem Programmstart aufruft und einen Zähler erhöht. Fertig.