Du bist nicht angemeldet.

Werbeanzeige

1

03.11.2013, 23:28

Socket Server und Client(wie aufbauen)`?

Hey Leute

Ich habe einige Fragen, bezüglich Socket, dem Server und dem Clienten, alles bezogen auf ein Spiel.

Zu aller erst, ich kann per recv() und send() Daten versenden, jetzt stellt sich für mich die Frage, wie verwalte ich das ganze mit dem Server.

Sollte ich mit einer Switch Anweisung überprüfen, welche funktion augerufen werden muss?
Oder lieber für jede Operation die vorkommen könnte ein eigenes Socket erstellen?


Wie verhält sich das ganze z.b beim Rendern, ich schätze mal ich übergebe Positionsdaten an die Clienten, wo welche Spieler b.z.w Bäume oder so stehen, und diese werden dann vom Clienten in einer Seperaten Funktion gerendet, oder liege ich da falsch?


Dann noch ein Beispiel: Wie würde sich das ganze bei einem Spiel wie Tekken über Socket verhalten, wenn ein Spieler den anderen trifft, wo wird die Kollision überprüft?

Mir geht es darum, die am besten geeignete Lösung für mein Projekt zu finden, ich habe zwar schon einige Ideen, aber wollte trotzdem vorher nochmal nachfragen, wie ihr darüber denkt :)

Ich hoffe ihr könnt mir da helfen

Gruß Leri

Schorsch

Supermoderator

Beiträge: 5 159

Wohnort: Wickede

Beruf: Student

  • Private Nachricht senden

2

04.11.2013, 00:21

Man versucht eigentlich möglichst viel Spiellogik auf dem Client zu berechnen. Es gibt natürlich auch ausnahmen, aber damit wirst du vermutlich am besten fahren. Ganz ohne Berechnung auf dem Client geht es aber normal auch nicht. Du hast halt eine Verzögerung, wenn du eine Eingabe vom Client zum Server sendest, da berechnest und zurück sendest. Damit das weniger auffällt wirst du eine Art von Client Side Prediction benötigen. Da lohnt es sich mal einzulesen. Ansonsten würde man nicht für jede Aktion einen Socket erstellen. Guck dir doch einfach mal bestehende Protokolle an. Erst mal musst du überlegen ob du deine Daten in Strings verpackt senden möchtest, oder als einfache Folge von Bytes. Strings haben den Vorteil lesbar zu sein, bringen aber je nach Anwendung ein wenig Overhead mit. Da musst du gucken was du wie oft senden möchtest und dich dann für ein Prinzip entscheiden. Ich finde es sinnvoll für verschiedene Typen von Nachrichten IDs zu verteilen. So kann eine Nachricht welche Positionsdaten überträgt eine eigene ID haben, eine Nachricht die einen Trigger auslöst eine andere und wiederum eine Chat Nachricht eine andere. So kannst du am Anfang die ID vergleichen und dann die Nachricht passend behandeln. Dafür macht eine eigene Schicht im Design durchaus sinn, kommt aber auch auf die Komplexität an. Ich denke am besten ist es wenn du einfach mal mit Sockets rum spielst. Ich hab erst einen kleinen Chat geschrieben, das ganze auf eine beliebige Anzahl von Clients erweitert und als nächsten Schritt ein kleines Top Down Spiel gemacht. Eigentlich weniger ein Spiel, jeder Client konnte einfach eine Spielfigur von oben bewegen. Dabei konnte ich mir was das Design angeht eine Vorstellung von allem machen und hatte einen Platz zum testen von Ideen. Mir hats geholfen. Versuch dich einfach Schritt für Schritt zum Ziel zu arbeiten.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Renegade123

Alter Hase

Beiträge: 477

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

3

04.11.2013, 00:39


Sollte ich mit einer Switch Anweisung überprüfen, welche funktion augerufen werden muss?
Oder lieber für jede Operation die vorkommen könnte ein eigenes Socket erstellen?

Du musst nicht für jede Operation einen Socket erstellen.
Ich denke, du solltest deine Daten serialisieren (Zeichenkette oder Byte), übermitteln und mittels einer Routine auswerten.
Wie du in der Routine verfährst hängt stark davon ab was du mit den Daten anstellst.


Wie verhält sich das ganze z.b beim Rendern, ich schätze mal ich übergebe Positionsdaten an die Clienten, wo welche Spieler b.z.w Bäume oder so stehen, und diese werden dann vom Clienten in einer Seperaten Funktion gerendet, oder liege ich da falsch?

Je nachdem was du auf deinem Server berechnet haben willst, musst du die entsprechende Daten übertragen.
Das rendern solltest du prinzipiell auf dem Client durchführen.
Im Allgemeinen ist es ratsam, so viel wie möglich auf dem Client durchzuführen.


Dann noch ein Beispiel: Wie würde sich das ganze bei einem Spiel wie Tekken über Socket verhalten, wenn ein Spieler den anderen trifft, wo wird die Kollision überprüft?

Du könntest die Überprüfung auf dem Client ausführen und den Server benachrichtigen was geschehen ist. Dieser kümmert sich dann um die weitere Übermittlung der Daten an andere Clients.


Mir geht es darum, die am besten geeignete Lösung für mein Projekt zu finden, ich habe zwar schon einige Ideen, aber wollte trotzdem vorher nochmal nachfragen, wie ihr darüber denkt :)


Erzähl uns mal mehr über dein Projekt.
Liebe Grüße,
René

4

04.11.2013, 01:07

nunja ein festes projekt ist es nicht, aber wie schorsch, hatte ich genau die gleichen Ideen.

Mittels SDl und Sockets wollte ich eine chat schreiben, und danach ein spiel, wo sich ein paar Spieler zeitgleich bewegen können.

Ich habe bereits mit Select gearbeitet, mein problem ist nicht, das verwenden von Sockets, sondern eher der aufbau.

Bei MMorpgs z.b gibt es immer packages, die ja auch im Server verarbeitet werden.

Meint ihr, ich soll mir einen String jedesmal schicken lassen, was direkt alle relevanten sachen enthält?

Ich denke bei der größe die dieser später haben würde, wäre das eher nicht so der bringer ^^.

und die überprüfung ist ja auch so ne Sache.

Ich hab bei recv und send imoment nur mit char gearbeitet, habe mich gefragt, ob die funktion auch integer und andere daten übermitteln kann, oder ob ich diese dann jedesmal selber danach, in den richtigen Datentyp umwandeln muss

BlueCobold

Community-Fossil

Beiträge: 10 871

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

04.11.2013, 06:37

Sende Kontext-relevante Pakete für einzelne Aktionen oder Aufgaben. Spieler benutzt Skill, Spieler bewegt sich, Monster verursacht Schaden, etc.
Es gibt im Netzwerk nur chars (bzw. Byte-Streams). Du musst die Pakete selbst serialisieren und deserialisieren. Dabei muss man unbedingt darauf achten, dass ein Paket nicht so ankommen muss, wie es versendet wurde. Aus einem abgeschickten Paket können also mehrere empfangene Pakete werden oder umgekehrt.
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]

6

04.11.2013, 08:49

okay, danke erstmal für die hilfe :) werde mich dann mal an einen kleinen Chat vorerst machen.

Melde mich, wenn es dann beim Spiel Probleme geben sollte :)

7

04.11.2013, 11:44

Schau Dir für's De-/Serialisieren mal protobuf von Google an (Diablo 3 verwendet das übrigens auch).
http://zeromq.org/ könnte auch was für Dich sein.

8

04.11.2013, 11:59

ich danke, werde es mir anschauen, fürs erste schreibe ich den Chat Server mal selbst, und das kleine Spiel, danach werde ich das wohl gut verwendet können :).

Möchte nur erstmal mit Der C++ Programmierer und Socket die Beispiele hinbekommen.

Also nochmal vielen vielen dank an alle :)

Thoran

Alter Hase

Beiträge: 512

Wohnort: Stuttgart

Beruf: Senior Software Engineer

  • Private Nachricht senden

9

04.11.2013, 13:12

Schau Dir für's De-/Serialisieren mal protobuf von Google an

Ich hab damit beim De-/Serialisieren nur gute Erfahrungen gemacht. Insbesondere gefällt mir, dass man Nachrichten hierarchisch schachteln kann, sozusagen kleine "Chunks" als Nachricht definieren und dann daraus die Gesamtnachricht zusammensetzen. Ich setze es deshalb auch bei mir zum Speichern von Szenen ein, auch wenn Google auf evtl. Performanceprobleme bei hoher Komplexität von Nachrichten hinweist. Beim Speichern seh ich da aber erstmal drüber hinweg.

Um zu zeigen was ich unter Komplex verstehe, hänge ich hier mal mein mit UML erstelltes Diagramm meines Protobuf-Formats für Szenen an. Ich habe hier Klassen als jeweils einzelne Nachricht verwendet (ich weiß, dass das nicht UML-Konform ist, also bitte keine Kommentare in diese Richtung). Die Kardinalität soll angeben, wie ich eine Nachricht in eine andere einbinden kann ( nur 1 mal, mind. 1-n mal oder 0 - n-mal), das übliche halt.

(Link)


Ein kleines Beispiel wie das Schachteln dann in protobufs Nachrichten format aussieht:
Bspw.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
message Adresse
{
    String name =0;
    Anschrift anschrift=1;
}

message Anschrift
{
    String strasse=0;
    int  hausnummer=1;
}


Außerdem ist protobuf sehr angenehm zu nutzen wenn sich dein Format ändern, sprich neuerer Code kann ohne Probleme das alte Format lesen und alter Code kann die neuen Dateien lesen (unter Ignorierung der neuen Einträge natürlich). Letzteres hab ich aber noch nicht wirklich ausprobiert.

Der Vollständigkeithalber weise ich darauf hin, dass man mit protobuf, das gesamte Format so dann auch übers Netz verschicken könnte, wenn man statt einem Filehandle ein Sockethandle verwendet, ob das Sinn macht sei dahingestellt.
Mein Entwicklertagebuch
Aktuelles Projekt: Universum Espionage
Eingestellt:Spieleengine SilverCore
Organisator "Spieleentwickler Stammtisch Stuttgart"

Werbeanzeige