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

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

1

31.07.2011, 13:49

Socket Programmierung: Problem mit "recv"

Hi, ich habe mich mal wieder der socket Programmierung gewidmet und habe eine Frage zur Funktion "recv":

Ich verwende TCP/IP und behandle jeweils "send" und "recv" in einem extra Thread - da sockets ja nur aus blokierenden Funktionen bestehen.
Jetzt behandle ich für den Server alle Clients ab und rufe für jeden "recv" auf, damit ich die Nachrichten erhalten, die die Clients dem Server senden.
Allerdings bleibt der Thread jetzt so lange in der "recv" Funktion stehen, bis eine Nachricht empfangen wurde.
Was soll man nun machen, wenn man z.B. ein Chat Programm hat (oder ein Spiel mit Chat Funktion) bei dem jeder Client nur ab und zu Nachrichten sendet.
Dann würde der Server einige Nachrichten erst viel zu spät erhalten, weil er an einem "recv" Aufruf hängt wobei schon ein weiterer Client eine Nachricht geschickt hat.
Natürlich könnte man jetzt für jeden Client einen extra Thread starten, aber dann geht die Performance sehr schnell in den Keller und die Threading
Programmierung wird noch chaotischer als sie ohne hin schon ist.

Wie löst man dieses Problem nun am geschicktesten?

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

31.07.2011, 14:09

Mit Hilfe von ioctlsocket kannst du in den Socket in den nonblocking Modus umstellen.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

idontknow

unregistriert

3

31.07.2011, 14:43

es gibt auch die Möglichkeit per FD_SET (das einzige was mir dazu noch einfällt) aus einem FD_SET = Socket Array die Sockets an denen nichts empfangen wird zu entfernen sprich du packst am Anfang alle deine Sockets da rein, wirfst die raus die ehh gerade nichts empfangen und den Rest kannste in einem Thread abarbeiten.

Dazu gibts die Funktion select, kuck dich mal auf der MSDN um könnte genau das sein was du brauchst :=)

http://msdn.microsoft.com/en-us/library/…1(v=vs.85).aspx

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

31.07.2011, 16:34

Ich rate zu der select-Lösung ggf in Kombination mit einen Thread. Die ist eigentlich recht performant und auch sonst sehr unproblematisch. Ich gehe mal davon aus, dass du gerne Netzwerkunterstützung in deine Engine einbauen möchtest. Wieviele Clients gedenkst du zu unterstützen weil ggf muss mann dann ein Macro umdefinieren damit das FD_SET genügend groß ist. Ansonsten könnte ein Blick in andere Netzwerklibs und wie die das Problem lösen, nicht schaden (oder du nutzt einfach direkt einer der fertigen Libs, die deinen Anforderungen entspricht).
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

5

31.07.2011, 17:32

Ok danke Leute, ich werd die select Funktion nutzen. Hab die Funktion schon längst wieder vergessen ^^. Das ist jetzt schon mein dritter Anlauf für eine NetzwerkLib aber bis jetzt komme ich gut voran.
Nur das Multithreading Crashsicher zu machen ist echt schwierig, selbst mit threadsicheren Klassen wie std::list, std::map usw.
PS: Ja, das ist als SubSystem für meine 3D Engine gedacht. Sollten schon so max. 32 Spieler möglich sein - damit das Limit nicht zu klein ist ;)

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

6

31.07.2011, 17:49

Ähm seit wann sind std::list und std::map threadsicher? Soweit ich weiß sind sie es per se nichtmal für den einfacheren "multiple read, one write" fall. Nur im Fall von "multilpe read, no write" sind sie nach meinem Kenntnisstand sicher.
Na ich wünsch dir viel Spass mit den vielen kleinen Ecken und Ösen des Netzwerken auf den unteren Ebenen. Ich würde mir das glaube ich nicht nochmal antun und gleich eine fertige Lib nutzen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

7

31.07.2011, 18:29

Nun gut, wenn du dir sicher bist, dass die STL container, list und map Klassen nicht thread-sicher sind, hole ich mir da einfach noch mal Rat bei meinen Kollegen auf der Arbeit.

Die "select" Implementierung funktioniert jedenfalls schon mal gut :) ist alles etwas kompliziert, low-level halt ^^ , aber scheint gut zu funktionieren.

Im Moment habe ich mit Abstürzen der Threads nur beim Disconnecten zu kämpfen.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

31.07.2011, 18:43

Meine aber auch dass die STL-Container Threadsicher sind. Ansonsten schreibst du dir zur Not eine Wrapper-Klasse drum rum und baust dir die locks selber ein.
„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.“

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

9

31.07.2011, 20:02

Also es kann durchaus sein, dass durch den neuen Standard sich da einige getan hätte, aber nach meinem Kenntnisstand hat die STL keinerlei Threading Mechanismen. Sprich weder Threads erstellen noch Mutex noch Critical Section noch Atomic Operations. Sprich wenn die STL Container threadsicher wären, so müsste die STL entsprechende Mechanismen nutzen und wäre es nur logisch dass es von der STL aus diese als Klassen/Funktionen/was auch immer was gäbe.
Natürlich ist es eine ganze Weile her, dass ich mich mit dem Thema genauer beschäftigt habe; um genau zu sein solange bis ich alle wichtigen Container in einer entsprechend threadsicheren Variante verpackt hatte. Seit dem Zeitpunkt nutze ich nur noch die entsprechenden Header von mir.

Wobei es schon interessant wäre, wenn es von der STL aus entsprechende Implementierungen gäbe. Dann könnte ich meine alten doch etwas naive Implementierung wegschmeißen (War damals zu faul die Iteratoren ebenfalls zu überladen, womit ich mir die Gefahr von nicht freigegebenen locks im Falle einer Exception an Bord geholte).
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

10

01.08.2011, 09:57

Ich würde sogar eher hoffen, dass die nicht per default threadsicher sind. Warum?

Es bereitet zur Laufzeit Zusatzaufwand und oft ist der gar nicht nötig. ;)
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Werbeanzeige