Networking-Framework für SDL-Projekt
-
Hi, erstmal danke für eure Beiträge
nwp3 schrieb:
Der Eventklasse eine virtuelle string serialize() und bool deserialize(string) geben würde den Events Pointer und Container erlauben.
Der Einfachheit halber habe ich darauf verzichtet. Aber der Ansatz ist auf jeden Fall interessant!
TyRoXx schrieb:
Du verwendest Exceptions, aber kein RAII. Deswegen hat deine Software sehr viele Ressourcenlecks.
Oh, da hast du verdammt recht! Hast du da einen Vorschlag? Prinzipiell sollte es ja reichen jeden (durch die aktuelle Funktion reservierten Speicher) freizugeben, bevor ich schließlich die Exception werfe, oder?
TyRoXx schrieb:
Du verwendest
malloc
und gibts den rohen Zeiger dann einfach an den Benutzer zurück (void* UdpLink::receive()
), welcher dann irgendwie herausfinden muss, dass er den Speicher mitfree
wieder freigeben muss und nicht etwa mitdelete[]
. Dabei prüfst du nicht den Rückgabewert vonmalloc
auf Null bevor du da reinschreibst.Zugegebene: das ist eine Schwäche meinerseits. Diesem Problem war ich mir bisher nicht bewusst. Wie würdest du an der Stelle arbeiten?
Was mir einfällt, wäre mit::operator new(len)
zu arbeiten (und natürlich auf NULL zu prüfen vor dem Schreiben )/EDIT: Ich glaube ich ziehe das Senden der Länge und der Daten mal auseinander, so dass die Senden- und Empfangen-Methode der von Link abgeleiteten Klassen mit Typparameter arbeiten und ich somit mit new Speicher anfordern kann.
TyRoXx schrieb:
Du nimmst an, dass
int
überall das gleiche Layout hat. Das fliegt dir plötzlich um die Ohren, wenn Computer mit verschiedener Endianness kommunizieren sollen.
Du verwendest verschiedene Typen für Längen in Bytes: Malint
, malunsigned long
, mal implizitsize_t
(das ist der Typ des Arguments vonmalloc
).Hab ich das echt noch gemacht? Verdammte Axt -.- Eigentlich wollte ich das vermeiden Danke für den Hinweis!
TyRoXx schrieb:
Du schreibst Fehlermeldungen manchmal in die Standardausgabe, anstatt sie einer Exception mitzugeben.
Uups xD Thx
rapso schrieb:
-was genau ist die zielgruppe? (der grund weshalb es sowas generisches nicht gibt es dass sowas sehr verbunden ist mit den restlichen systemen, bei netzwerk code sind subtile dinge oft die entscheidenen. und, RTS, FPS, Sims etc. haben alle andere anforderungen).
Ich arbeite an einem Multiplayer-RPG mit isometrischer Darstellung. Der Haupteinsatzzweck soll der Einsatz dort sein. Zusätzlich hatte ich mit Clint Bellanger (falls den jemand kennt^^) geschrieben (er arbeitet an der Singleplayer-RPG Engine "FLARE") und ihm angeboten, dass er ggf. den Code irgendwann bei sich integrieren kann, wenn er mal auf Multiplayer-Support umsteigen will.
rapso schrieb:
-ist kompressions schon eingebaut?
Nein, noch nicht.
rapso schrieb:
-welche architektur supportest du? (client<->client,client<->server,...?)
Das zweite Beispielprogramm implementiert einen Server mit n Clients. Aber Prinzipiell wäre auch Host-to-Host möglich, wenn man auf der NetworkingQueue Klasse aufbauend eine ähnliche Architektur implementiert. Die Idee finde ich gar nicht so schlecht
rapso schrieb:
-ist die reihenfolge garantiert bei allen?
Was meinst du damit genau?
rapso schrieb:
-wie schaut die lib aus in vergleich zu anderen wie z.b. RakNet? (gibt es was, was besonders gut ist, etwas, was fehlt aber noch reinkommt?)
Ich muss ganz ehrlich sagen, dass ich mir andere Libs nicht ins Detail angeschaut habe. Von daher kann ich nur darüber sprechen, was ich zukünftig noch geplant habe (siehe "Scheduled Changes" in der README).
rapso schrieb:
-support von low priority dingen ala file transfer/streaming?
Das habe ich bisher nicht vorgesehen
rapso schrieb:
-support auf router konfiguration?
Auch hier muss ich fragen: Was genau meinst du?
Ich werde je nach Zeit mal die genannten Probleme angehen.
LG Glocke
-
Hallo zusammen,
ich habe noch einige Dinge verbessert und umgebaut. Wäre cool wenn mir jemand noch Hinweise wegen Memory Leaks geben könnte. Ich arbeite zwar mit Valgrind, aber manchmal werde ich aus dem Meldungen auch nicht ganz schlau. Blöderweise habe ich jetzt gerade keine explizite Meldung da zum fragen ... vielleicht hat jemand ein Auge für sowas
LG Glocke
/EDIT: Doch, einen konkreten Fall im Bezug auf die example1.cpp habe ich hier:
==13560== Thread 4: ==13560== Syscall param socketcall.send(msg) points to uninitialised byte(s) ==13560== at 0x042e9808: send (socket.S:100) ==13560== by 0x040ee166: SDLNet_TCP_Send (in /usr/lib/i386-linux-gnu/libSDL_net-1.2.so.0.0.7) ==13560== by 0x0804b25c: TcpLink::send_ptr(void*, unsigned int) (connection.hpp:131) ==13560== by 0x0804acf0: trigger_sender(void*) (eventsystem.cpp:24) ==13560== Address 0x4c723f9 is 257 bytes inside a block of size 258 alloc'd ==13560== at 0x0402b9b4: operator ==13560== by 0x0804d3a8: tcp_demo() (example1.cpp:71) ==13560== by 0x0804d69c: main (example1.cpp:181) ==13560== Uninitialised value was created by a heap allocation ==13560== at 0x0402b9b4: operator ==13560== by 0x0804d3a8: tcp_demo() (example1.cpp:71) ==13560== by 0x0804d69c: main (example1.cpp:181) ==13560==
Liegt der Fehler an mir? Wenn ja wo ..
-
Hallo,
in den letzten Wochen habe ich das Framework ein ganzes Stück umkonzipiert - auch basierend auf einigen der hier angesprochenen Probleme:
Kommunikation auf Basis von JSON
- Daten werden in JSON-Objekten gesammelt und können serialisiert / deserialisiert werden. Die gängigen Container können in JSON-Objekte abgebildet werden.
- Einige Speicherlecks beim Werfen von Exceptions wurden behoben. (aber sichtlich noch nicht alle!)
- Beim Lesen der JSON-Objekte wird nicht mehr mit malloc und void-Pointern gearbeitet. Statt dessen wird auf das Mittel der Deserialisierung zurückgegriffen und ein neues JSON-Objekt erstellt, das mittels delete gelöscht werden kann. Dadurch wurden einige Speicherlecks behoben.
- Probleme aufgrund verschiedener Größen von Datentypen wurden durch (die von C++11 gegebenen) Datentypen mit fester Länge (z.B. std::uint32_t - siehe http://en.cppreference.com/w/cpp/types/integer) eingedämmt. Soweit ich es überblicke, habe ich bereits das ganze Framework auf diese Typen umgebaut - oder fast das ganze ^^
- Weitere plattformspezifische Probleme wurden durch die Serialisierung / Deserialisierung verringert. Mir ist derzeit erstmal kein weiteres Problem bewusst - ich bin aber offen für neue Probleme
- Komprimierung ist bisher noch nicht eingebaut. Da aktuell aber serialisierte JSON-Objekte als Zeichenkette versandt werden, erscheint ein nachträgliches Implementieren einer Komprimierung bzw. Dekomprimierung recht einfach.
- Bislang wird ausschließlich die Client-Server-Architektur unterstützt. Wenn jemand Interesse an einer Peer-to-Peer-Implementierung hat, kann ich da ggf. etwas bauen. Hat jemand eine Peer-to-Peer-Implementierung auf Basis des Frameworks, bin ich gerne bereit mir die anzuschauen und ggf. hinzuzufügen.
- Es gibt aktuell genau eine Beispiel-Anwendung: Ein Konsolen-Chatroom. Siehe https://github.com/cgloeckner/networking
Es würde mich freuen, wenn der ein oder andere das Framework mal etwas auf den Zahl fühlen möchte. Für Fehler/Probleme/Anregungen/Kritik und Lob stehe ich gern zur Verfügung
Falls ich Eure Fragen noch nicht (vollständig) beantwortet habe, dann fragt bitte ruhig nochmal
LG Glocke
PS: Kann jemand das "event-based" aus dem Titel nehmen?Das kann ich ja sogar selber
-
*push in der Hoffnung auf weiteres Feedback*
-
ohn es mir angeschaut zu haben: hast du dir mal boost::mpi angeschaut? MPI löst ähnliche Probleme, aber da kannst du dir zum Beispiel anschaueen, wie du deine srialisierung ordentlich hinkriegst.
Ich verstehe nicht, warum du JSON verwendest? tut das not?
-
otze schrieb:
Ich verstehe nicht, warum du JSON verwendest? tut das not?
Ich verstehe nicht, warum nicht JSON. Es war die erste Wahl: es ist übersichtlich, verbreitet und hat imho geringeren Overhead als XML.
-
wenn du eh nur primitive verschickst, wieso schickst du die daten nicht einfach als raw packet?
-
rapso schrieb:
wenn du eh nur primitive verschickst, wieso schickst du die daten nicht einfach als raw packet?
(1) "Zukunftssicherheit" - wenn ich irgendwann mehr als Primitive geschicken will, habe ich "vorgesorgt".
(2) Little Endian vs. Big Endian vs. weitere exotische Bytereihenfolgen.
-
Dazu muesstest du das Jetzt erstmal in den Griff bekommen: Robustheit vs Fehler. Weiterhin muss auf beiden Seiten (Client/Server) serialisiert und deserialisiert werden, das kostet Performance und ist ein mehr an Aufwand im Vergleich zum einfachen Verwenden des Integeres in binaer. Auch mag Genauigkeit bei Fliesskommazahlen verloren gehen, ... Alles hat Vor- und Nachteile. Und wenn du auf Zukunftsicherheit setzen moechtest, dann suche dir eine andere Bibliothek oder mache alles gleich mit der POSIX-Api.
-
knivil schrieb:
Weiterhin muss auf beiden Seiten (Client/Server) serialisiert und deserialisiert werden, das kostet Performance und ist ein mehr an Aufwand im Vergleich zum einfachen Verwenden des Integeres in binaer.
Das ist richtig. Mit diesem Mehraufwand kann man entweder leben oder nicht. Jedes Framework hat seine Einsatzgebiete und seine Grenzen. Die Grenzen meines Ansatzes liegen klar bei der Performance: für ein MMORPG wird die Implementierung nicht taugen - für ein "kleines" Spiel (mit z.B. 5-6 Spielern) sollte es hingegen schon funktionieren.
knivil schrieb:
Und wenn du auf Zukunftsicherheit setzen moechtest, dann suche dir eine andere Bibliothek oder mache alles gleich mit der POSIX-Api.
Ich hatte "Zukunftssicherheit" absichtlich in "-Zeichen gesetzt; was ist in der Informatik schon zukunftssicher Ich meinte damit viel mehr, dass es auf spätere Änderungen möglichst flexibel reagiert.
Die genauen Gründe für die Verwendung eines Serialisierungsansatzes habe ich in der Readme auf GitHub ausformuliert: https://github.com/cgloeckner/networking#why-serialization
LG Glocke