Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Frage zu UDP

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
24.07.2009, 20:09 Uhr
Lolius



Hi
Hoffe bin hier im richtigen Thema.

Ich programmiere eine Netzwerk Engine in C++ die ich dann in eine Game Engine inkludieren
will.

Die Netzwerk Engine soll möglichst schnell sein, denn Sie soll so viele Spieler die möglich
Handlen können.

Ich hab ein Accept-Thread gemacht, der läuft in einer While schleife und jeder Client
der sich verbindet wird in eine Liste aufgenommen.
Etwa so (sehr vereinfacht):


C++:
Client ClientArray[500];

class Client
{
   TCPSocket tcp;
   UDPSocket udp;

   id;
};



Der Client wird also an einen freien Platz verwiesen.
Und da ich die TCP Verbindung
"akzeptieren" kann (tempSocket=accept(acceptSocket,NULL,NULL), kann ich
das akzeptierte Socket dem Client Array übergeben:

ClientArray[54].tcp = tempSocket;

Aber bei UDP Verbindung gibts das nicht!
UDP Verbindungen kann man nicht akzeptieren und zuweisen.

Gibts dafür ne Lösung?

Ich könnte einfach ein Thread machen, der die UDP daten für alle Clienten
Empfängt und den Clienten weiterleitet.
Ist dies schnell genug, wenn ich zb 300 connections habe, welche je alle 200ms
Daten senden?

Hoffe jemand versteht mein Problem!

Danke für euere Bemühungen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
25.07.2009, 08:27 Uhr
ao

(Operator)



Zitat von Lolius:

Aber bei UDP Verbindung gibts das nicht!
UDP Verbindungen kann man nicht akzeptieren und zuweisen.


Nein, weil es UDP-"Verbindungen" in dem Sinne gar nicht gibt. Bei TCP kannst du den Socket als Handle für die Verbindung nehmen.

Bei UDP landen die einlaufenden Pakete aller Clients auf demselben Socket. Um daraus ein eindeutiges Handle zu bilden, musst du die IP-Adresse und den Port des Clients noch hinzunehmen (und hoffen, dass nicht mehrere Clients hinter demselben Router sitzen und durch NAT wie ein einziger aussehen).


Zitat:
Ist dies schnell genug, wenn ich zb 300 connections habe, welche je alle 200ms
Daten senden?


Was meinst du mit schnell genug?

Das sind 60.000 Packets und mindestens 2,7 MBytes pro Sekunde, plus die im UDP-Packet enthaltenen Nutzdaten (jedes Byte mal 60.000).

Auf einem Gigabit-Ethernet könnte das gehen.

Ein Fast-Ethernet ist damit zu rund 30 Prozent voll (und der Server wird ja auch noch antworten müssen, das kommt noch dazu), da wirst du eine erhebliche Kollisionsrate haben.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
25.07.2009, 15:14 Uhr
0xdeadbeef
Gott
(Operator)


Äh...300 Verbindungen mit je 5 Paketen pro Sekunde sind 1500 Pakete pro Sekunde. IP- und UDP-Header zusammen belaufen sich auf 20 Byte, d.h. 30 kB/s Minimalverkehr.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
25.07.2009, 20:35 Uhr
ao

(Operator)



Zitat von 0xdeadbeef:
Äh...300 Verbindungen mit je 5 Paketen pro Sekunde sind 1500 Pakete pro Sekunde.

Äh ... stimmt. Falschrum gedacht.


Zitat:
IP- und UDP-Header zusammen belaufen sich auf 20 Byte, d.h. 30 kB/s Minimalverkehr.


Paar mehr sinds schon.

IP-Header: 20 Bytes, evtl. mehr, falls Options angehängt sind.
UDP-Header: 8 Bytes.
Ganz außen drumherum noch der Ethernet-Frame (18 Bytes) und die Präambel (8 Bytes)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
25.07.2009, 20:45 Uhr
0xdeadbeef
Gott
(Operator)


Eh, ja, mit dem IP-Header hab ich mich verdacht. 28 Byte ist richtig. Ob allerdings ein Ethernet-Frame (oder irgend etwas anderes) drumherum kommt, hängt davon ab, ob das ganze über ein Ethernet-Interface geht. Ich bin auch nicht sicher, wie die ISPs den Verkehr abrechnen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 25.07.2009 um 20:46 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
26.07.2009, 01:41 Uhr
Lolius



Hi
Danke für eure Antworten!

Also +- 30Kb/s + noch die Daten finde ich eigentlich recht wenig. Da könnte man ja
theoretisch 1000 Spieler verwalten, falls die Rechenleistung mitmacht, denn so ein richtiger
Server hat schon ziemlich Bandbreite.

Also TCP Header hat 28 Byte und ein UDP Header 8 Byte?
Das ist interessant.

Also spart man mit UDP nur 20 Bytes pro Paket.

Rentiert das überhaupt?

Das sind in der Sekunde 100 Bytes mehr oder Weniger - was macht das schon aus.

Denkt ihr das auch?

Das sind fast 30 kb in der Sekunde bei 300 Spielern.

Findet ihr, dass es Sinn macht, eine Netzwerkengine mit UDP auszustatten?
Oder ist UDP viel schneller als TCP? Weil für die Positions Aktualisierung
der Entitys (zb Spieler im Game) ist das schon ein Argument.

Aber ich mach die Engine ja nicht speziell für Egoshooter, sondern eher für
Spieleerlebnisse mit vielen Spielern.

Ich baue da auf das System von WoW: Der Server verzögert die Positions-aktualisierung
der Spieler um etwa 500ms. Das heisst wenn ich jetzt loslaufe, dann sehen mich die andern Spieler erst in 500ms loslaufen.
So reicht es, wenn man nur alle 200-400ms Datenpakete verschickt.

Was meint ihr dazu?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
26.07.2009, 02:23 Uhr
0xdeadbeef
Gott
(Operator)


Wie viel der Overhead ausmacht, hängt davon ab, wie viel pro Paket gesendet wird. Und auch davon, was die Anwendung nachher können soll - wenn du in UDP praktisch TCP-Verbindungen emulieren willst, macht das eher wenig Sinn. Allerdings ist der Paketheader nicht der einzige Overhead, den es zu bedenken gilt (siehe unten).

Der wesentliche Unterschied ist, dass TCP auf Zuverlässigkeit ausgelegt ist, UDP auf Geschwindigkeit.

Bei einer TCP-Verbindung unternehmen beide Seiten einiges, um Datenintegrität sicher zu stellen - zum Beispiel wird jedes Paket bestätigt und erneut gesendet, wenn die Bestätigung nicht schnell genug eintrifft, der Kernel überprüft die Prüfsumme im Header und sortiert die Pakete anhand der Sequenznummer. Das führt zu mehr Rechenarbeit und über unzuverlässige Netze auch zu höheren Latenzzeiten. Wenn jemand zum Beispiel einen kaputten Router hat, kann das deutlich mehr Arbeit bedeuten, allerdings ist auch (ziemlich) sicher gestellt, dass das, was gesendet wird, auch ankommt.

UDP dagegen schickt den Kram stumpf raus, in der Hoffnung, dass er auch ankommt. Das garantiert in kurze Latenzzeiten, nur muss die Anwendung in der Lage sein, mit fehlenden und/oder in falscher Reihenfolge eintreffenden Paketen umzugehen. Das ist vor allem dann sinnvoll, wenn verlustbehaftete Datenübertragung nicht so tragisch und zeitnahe Auswertung essentiell ist (beispielsweise Telefonie oder Radio).

Ich bin jetzt kein Experte, was Spiele angeht, aber meines Wissens benutzen Echtzeit-Internet-Spiele häufig UDP wegen der zeitnahen Auswertung und betreiben üblicherweise eine Art Synchronisation zwischen Server und Client, d.h., der Client rechnet eine bestimmte Zeit für sich selbst und teilt dem Server alle halbe Sekunde oder so mit, was er gemacht hat (und umgekehrt). Gehen Pakete verloren, gibt es Lagging-Effekte. Es liegt dann an der Anwendung, Integrität zwischen Client und Server sicherzustellen.

Was für deinen Use Case angemessen ist, musst du selbst beurteilen - im Wesentlichen solltest du dich fragen, wie der Kram sich verhalten soll, wenn es Netzwerkprobleme gibt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 26.07.2009 um 02:27 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
26.07.2009, 11:51 Uhr
Lolius



Ja das ist sicher eine Herausforderung mit den UDP Paketen.
Ich hatte eigentlich vor über UDP nur die Position der Entitys zu aktualisieren, alle 200 -400ms.
Und alle andere (Chatnachrichten, Energieveränderungen etc) über
TCP und das alle 500-1000ms.

Das wichtigste ist aber:

Können die UDP Pakete nur in falscher Reihenfolge eintreffen oder auch die Pakete selbst
in falscher Reihenfolge oder teilweise?

Ich sende "Hallo Welt" über UDP.

Möglichkeiten:

- Gar kein eintreffen
- "Hallo We" (teilweise)
- "Hoall Wtel" (falsche Reihnflg.)

Das ist sehr wichtig zu wissen

Und danke für deine Bemühungen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
26.07.2009, 16:10 Uhr
0xdeadbeef
Gott
(Operator)


Nein, die Pakete wird dir der IP-Stack schon zusammensetzen. Wenn du allerdings "Hallo" und "Welt" in zwei Paketen abschickst, kann es sein, dass du das "Welt"-Paket vor dem "Hallo"-Paket bekommst. Wie wahrscheinlich das ist, ist eine andere Frage - besonders, wenn du die Pakete in relativ langen Abständen voneinander absendest.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: