Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

41

29.01.2014, 10:37

Ich weis, dass es vielleicht etwas doof kommt, so ein Thema nochmal aufzugreifen, aber ich habe auch nach stundenlanger Bing-Suche nichts gefunden :dash: Also nun zum eigentlichen Problem: ich verwende nun die Netzwerk-Lib von SFML (danke für den guten Tipp :D ), und bin auf die Funktion

C-/C++-Quelltext

1
sf::IpAddress::getPublicAddress()
gestoßen, und da dachte ich mir, zum experimentieren wäre meine globale Adresse sehr spaßig. Deshalb verwende ich in meiner kleinen Netzwerk-Klasse folgende Funktion:

C-/C++-Quelltext

1
2
3
4
5
// globale IP 
sf::IpAddress CNetzwerk::getPublicIP() 
{
publicIP = sf::IpAddress::getPublicAddress();return publicIP; 
}

Was soll denn das? Wozu kapselst Du einen Aufruf einer einzelnen Funktion in eine andere Funktion? Das ist doch total überflüssig.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

42

29.01.2014, 12:56

Kann sowas nicht Sinn machen und Abhängigkeiten zu bestimmten Bibliotheken zu minimieren? Ich habe z.B. auch eine Kameraklasse, wo teilweise nur ein einzelner Funktionsaufruf der entsprechenden Kamera-API in einer Funktion gekapselt ist. Benutze ich jetzt eine andere Kamera(-API), dann muss ich nur in meiner Kameraklasse die Funktion ändern anstatt überall im Code rumzuwuseln.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

43

29.01.2014, 13:26

Es würde Sinn ergeben, wenn der Rückgabewert einen anderen Typ hätte. Hat's aber nicht und es ist nur ein überflüssiger Wrapper.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Gelöschter Benutzer

unregistriert

44

29.01.2014, 14:19

Problembeschreibung

In diesem Beitrag möchte ich auf das folgende Problem eingehen: die SFML-Funktion "sf::IpAddress::getPublicIP()" funktioniert bei mir nicht. Zuerst möchte ich allerdings auf meine Programme und Linkereinstellungen und CO. überkommen. Ich verwende Visual Studio 2012 Express, diese Anwendung ist in C++ geschrieben und als Bibliothek dient die aktuelle Version der SFML (2.1). Ich werde versuchen die Linkereinstellungen als Bild beifügen, falls es nicht geht, bitte schreiben. Welche "Sachen" ich einbinden muss habe ich von dieser Seite: KlickMich. Dort habe ich alle Schritte wie gezeigt befolgt. Als Nächstes werde ich meine Klasse CNetzwerk erklären, welche auf eine .hpp- und .cpp-Datei "aufgeteilt" ist. Ich werde als erstes den Quellcode posten, dann zur Erklärung übergehen. Hier die Header-Datei:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <string> 
#include "SFML\Network.hpp" 

class CNetzwerk 
{ 
public: 
CNetzwerk(); // Konstruktor 
~CNetzwerk(); // Destruktor 
sf::IpAddress getPublicIP(); // liefert die globale IP 
sf::IpAddress getLocalIP(); // liefert die lokale IP 
sf::IpAddress getLastIP(); // liefert die IP des Absenders des letzten angekommenen Paketes 
std::string receive(); // Daten empfangen 
void send(std::string _data, int _Empfänger); // Daten verschicken 
void blocking(bool _Block); // Blocking ein- oder ausschalten 
unsigned short getPort(); // liefert den Port 

private: 
sf::IpAddress publicIP; // globale IP-Adresse des Servers 
sf::IpAddress localIP; // lokale IP-Adresse des Servers 
sf::UdpSocket *m_psocket; // Zeiger auf Socket-Instanz 
sf::IpAddress IP_01; // IP-Adresse von Spieler 1 
sf::IpAddress IP_02; // IP-Adresse von Spieler 2 
sf::IpAddress IP_sender; // IP-Adresse des letzten eingegangenen Packetes 

unsigned short m_Port; // Port von Server 

};

Dies ist die Header-Datei "CNetzwerk.hpp". Sie ist für sämtliche Netzwerk-Aufgaben gedacht.



Zitat

von BlueCobold: Was soll denn das? Wozu kapselst Du einen Aufruf einer einzelnen Funktion in eine andere Funktion? Das ist doch total überflüssig.


Ich dachte mir ich speichere die globale IP-Adresse in "publicIP". So muss ich nicht jedesmal die Funktion aufrufen, um die IP zu erfahren. Ich wollte noch eine "get-Funktion" einbauen. So muss ich die Funktion nur einmal aufrufen, denn ich meine gelesen zu haben, dass die Funktion "sf::IpAddress::getPublicIP()" eine Verbindung zu "whatismyip.com" aufbaut (ich bin mir nicht sicher, ob die Seite so heißt). Ich dachte das verringert das Fehlerrisiko, ich lasse mich aber gerne verbessern. Die einzelnen Funktionen sind denke ich gut durch ihre Kommentare beschrieben. Für "sf::IpAddress IP_01" und "sf::IpAddress IP_02" muss ich mir noch etwas einfallen lassen. "m_Port" wird aus einer .ini-Dateien geladen, damit der Anwender, selbst entscheiden kann, welchen Port er verwenden möchte. Ich gehe nun zur .cpp-Datei "CNetzwerk.cpp" über:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <Windows.h> 
#include <iostream> 
#include "CNetzwerk.hpp" 

// Konstruktor 
CNetzwerk::CNetzwerk() 
{ 
m_psocket = new sf::UdpSocket; // Neue UdpSocket-Instanz 

m_Port = GetPrivateProfileIntA ("network", "port", 0, "Config/network.ini"); 

if (m_psocket->bind(m_Port) != sf::Socket::Done) 
{ 
std::cout << "[FEHLER] Socket anbinden!" << std::endl; 
} 

m_psocket->setBlocking(true); // Blocking standardmäßig an 

localIP = getLocalIP(); 

IP_01 = "127.0.0.1"; 
} 

// Destruktor 
CNetzwerk::~CNetzwerk() 
{ 
if (m_psocket != nullptr) 
{ 
delete m_psocket; 
m_psocket = nullptr; 
} 
} 

// senden von Daten 
void CNetzwerk::send(std::string _data, int _Empfänger) 
{ 
if (_Empfänger == 0 && localIP != "") 
{ 
if (m_psocket->send(_data.c_str(), 100, localIP, m_Port) != sf::Socket::Done) 
{ 
std::cout << "[FEHLER] Uebertragung von UDP-Paket an: " << localIP << std::endl; // Fehler... 
} 
else 
{ 
} 
} 
else if (_Empfänger == 1 && IP_01 != "") 
{ 
if (m_psocket->send(_data.c_str(), 100, IP_01, m_Port) != sf::Socket::Done) 
{ 
std::cout << "[FEHLER] Uebertragung von UDP-Paket an: " << IP_01 << std::endl; // Fehler... 
} 
else 
{ 
} 
} 
else if (_Empfänger == 2 && IP_02 != "") 
{ 
if (m_psocket->send(_data.c_str(), 100, IP_02, m_Port) != sf::Socket::Done) 
{ 
std::cout << "[FEHLER] Uebertragung von UDP-Paket an: " << IP_02 << std::endl; // Fehler... 
} 
} 

} 

// empfangen von Daten 
std::string CNetzwerk::receive() 
{ 
char data[100] = ""; 

std::size_t received; 

if (m_psocket->receive(data, 100, received, IP_sender, m_Port) != sf::Socket::Done) 
{ 
std::cout << "[FEHLER] Empfangen von UDP-Paket von: " << IP_sender << std::endl; // Fehler... 
} 

std::string sData = data; 

return sData; 
} 

// liefert Port 
unsigned short CNetzwerk::getPort() 
{ 
return m_Port; 
} 

// Blocking ein- oder ausschalten 
void CNetzwerk::blocking(bool _Block) 
{ 
if (_Block == true) 
{ 
m_psocket->setBlocking(true); // Blocking einschalten = true 
std::cout << "Blocking eingeschalten!" << std::endl; 
} 
else if (_Block == false) 
{ 
m_psocket->setBlocking(false); // Blocking ausschalten = false 
std::cout << "Blocking ausgeschalten!" << std::endl; 
} 
else 
{ 
std::cout << "[FEHLER] Blocking konnte nicht ein- oder ausgeschalten werden!" << std::endl; 
} 
} 

// globale IP 
sf::IpAddress CNetzwerk::getPublicIP() 
{ 
publicIP = sf::IpAddress::getPublicAddress(); 
return publicIP; 
} 

// lokale IP 
sf::IpAddress CNetzwerk::getLocalIP() 
{ 
localIP = sf::IpAddress::getLocalAddress(); 
return localIP; 
}

Ok, eigentlich glaube ich gibt es hier nicht sehr viel zu erzählen, falls doch, bitte einfach schreiben, ich werde versuchen bei der nächsten Möglichkeit zu antworten. Vermutlich gibt es etwas an dem Code auszusetzen, allerdings müsst ihr berücksichtigen, dass ich "erst" C++ für Spieleprogrammierer durch habe, und nun mit Davids Buch anfange. Natürlich war ich mit "C++ für Spieleprogrammierer" nicht erst gestern fertig. Ich werde jetzt versuchen die Bilder anzufügen, hoffentlich sind es auch die Richtigen, ich habe auf "Alle Konfigurationen" gestellt:

Bild1: Linker -> Eingabe -> Zusätzliche Abhängigkeiten (sfml-network-d.lib ist verdeckt)

Nun die Fehlerbeschreibung von Visual Studio:

Fehler 1 error LNK2001: Nicht aufgel÷stes externes Symbol ""public: static class sf::Time const sf::Time::Zero" (?Zero@Time@sf@@2V12@B)".

Fehler 2 error LNK1120: 1 nicht aufgel÷ste Externe C:\Users\Alexander\documents\visual studio 2012\Projects\RPG - Server\Debug\RPG - Server.exe 1 1 RPG - Server




Meine Vermutung ist das irgendetwas nicht mit dem Paramater der Funktion "getPublicIP" stimmt, allerdings weis ich nicht weiter, und glaube, man muss keinen Parameter übergeben, was dieses Zitat von der offizielen Seite (KlickMich)bestätigt:



Zitat

The public address is the address of the computer from the internet point of view, i.e. something like 89.54.1.169. It is necessary for communications over the world wide web. The only way to get a public address is to ask it to a distant website; as a consequence, this function depends on both your network connection and the server, and may be very slow. You should use it as few as possible. Because this function depends on the network connection and on a distant server, you may use a time limit if you don't want your program to be possibly stuck waiting in case there is a problem; this limit is deactivated by default.


Ich hoffe das jemand von euch eine Ahnung hat,

Mit freundlichen Grüßen,

alex41018
»Gelöschter Benutzer« hat folgendes Bild angehängt:
  • Bild1.png

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »alex41018« (29.01.2014, 14:28)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

45

29.01.2014, 15:34

Du musst keine Vermutungen aufstellen, weil schon lang klar ist wo das Problem liegt.

Zitat

sfml-network-d.lib ist verdeckt

Das -d steht für Debug und gehört auch nur in den Debugmodus.
In den Releaseeinstellungen trägst du die Dateien ohne -d ein.
Das dürfte dein Problem lösten.

Du fängst mit Davids Buch an? Super! Du hast es aufgegeben die Releativitätstheorie und die Stringtheorie zu vereinheitlichen um jetzt zu versuchen, einen Fusionsreaktor zu bauen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »NachoMan« (29.01.2014, 15:40)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

46

29.01.2014, 15:39

Ich dachte mir ich speichere die globale IP-Adresse in "publicIP". So muss ich nicht jedesmal die Funktion aufrufen, um die IP zu erfahren.
Schlechte Idee. Was, wenn sich während des Programmlaufs die IP ändert, weil jemand die Verbindung getrennt hat? Zum Beispiel der 24h-Disconnect bei vielen Providern? Oder der User hat sich neu in's Netzwerk eingeklinkt mit seinem Mobile-Stick oder geht per WLAN in ein anderes Netz. Oder für what-fcking-reason-ever die IP-Adresse sich ändert? Dann wäre es ganz schlecht das dauerhaft zu cachen. Kurzzeitig ist sicher eine gute Idee, aber nicht auf Dauer.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Gelöschter Benutzer

unregistriert

47

29.01.2014, 17:55

@NachoMan: Danke für den Typ, daran hat es leider auch nicht gelegen, an dem "-d", weder im Debug oder Releasemodus. Auch mal mit und ohne "-d".

@BlueCobold: Ok, vielen Dank, sehr guter Grund, werde ich auf jeden Fall beherzigen, wobei es denke ich nicht so viel Rolle bei mir spielt, weil das Programm, bzw. die .exe, sowieso nicht auf einen Server kommt. Die Anwendung wird immer neugestartet, wenn man spielen möchte

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »alex41018« (31.01.2014, 14:08)


Gelöschter Benutzer

unregistriert

48

31.01.2014, 18:11

Leider konnte ich das Problem immer noch nicht lösen. Deshalb wollte ich mich erkundigen, ob mir vielleicht jemand ein funktionierendes kleines Projekt zuschicken kann, welches lediglich die globale IP des Computers mithilfe der SFML 2.1 herausfindet. Dann könnte man denke ich feststellen, ob das Problem vielleicht nur auf meinem Computer auftritt.

Mit freundlichen Grüßen,

alex41018

49

31.01.2014, 18:16

C-/C++-Quelltext

1
2
3
4
5
6
7
8
#include <SFML/Network/IpAddress.hpp>
#include <iostream>

int main()
{
    std::cout << sf::IpAddress::getPublicAddress(); //explizite Konvertierung durch definierten <<-Operator für sf::IpAddress nicht benötigt
    return 0;
}


MfG
Check

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Checkmateing« (31.01.2014, 19:15)


Gelöschter Benutzer

unregistriert

50

31.01.2014, 18:22

Leider kommen dort die selben Fehlermeldungen :( "::toString()" hat nicht funktioniert, so sieht mein Programm aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
#include <SFML/Network/IpAddress.hpp> 
#include <iostream> 

int main() 
{ 
    std::cout << sf::IpAddress::getPublicAddress() << std::endl; 
    std::cin.get(); 
    return 0; 
}

Werbeanzeige