mikrocontroller.net

Forum: PC-Programmierung SDL Net Server


Autor: Halgn H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab ein großes Problem: Ich will ein Netzwerkspiel machen, aber ich 
schaf es nicht den server zu programmieren. Der Server soll nur Clients 
Hinzufügen und clients löschen wenn sie nicht mehr da sind. Dabei darf 
er nicht abstürzen. Er soll bis 50 Leute nehmen...

Wer das mir macht bekommt sogar von mir Geld(PayPal). Wie viel hängt am 
server ab.

Also was er machen soll:
- Clients hinzufügen
- Clients daten geben (x & y von den andren spielern)
- Nicht abstürzen wen ein Client geht
#include <SDL/SDL.h>
#include <SDL/SDL_net.h>
#include <stdlib.h>
#include <stdio.h>

int player_x[50];
int player_y[50];

int main ( int argc, char** argv )
{
  IPaddress address;
  TCPsocket sock_server, sock_client[50];
  SDLNet_SocketSet set;
  int wait, num_clients, data, ready;


  if(SDL_Init (0) ==-1)
    {
      printf ("SDL_Init: %s\n", SDL_GetError ());
      exit (1);
    }
  if(SDLNet_Init () ==-1)
    {
      printf ("SDLNet_Init: %s\n", SDLNet_GetError ());
      exit(1);
    }
  if (SDLNet_ResolveHost (&address, NULL, 10000) == -1)
    {
      printf ("SDLNet_ResolveHost: %s\n", SDLNet_GetError ());
      SDLNet_Quit ();
      exit (1);
    }
  sock_server = SDLNet_TCP_Open (&address);
  if (!sock_server)
    {
      printf ("SDLNet_TCP_Open: %s\n", SDLNet_GetError ());
      SDLNet_Quit ();
      exit (1);
    }

  printf ("Init finished. Wait for clients...\n");

  wait = 10;
  num_clients = 0;
  do
    {
      SDL_Delay (1000);
      sock_client[num_clients] = SDLNet_TCP_Accept (sock_server);
      if (sock_client[num_clients])
        {
          printf ("accepted %d\n", num_clients + 1);
          num_clients++;
        }
      wait--;
    } while ((num_clients < 50) && (wait > 0));

  if (wait > 0)
    {
      /* Jetzt haben wir Clients */

      /* Platz für Sockets machen*/
      set = SDLNet_AllocSocketSet (50);
      if (!set)
        {
          printf ("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError ());
          exit (1);
        }
      SDLNet_TCP_AddSocket (set, sock_client[0]);
      if (SDLNet_TCP_AddSocket (set, sock_client[1]) != 2)
        {
          printf ("SDLNet_TCP_AddSocket: %s\n", SDLNet_GetError ());
          exit (1);
        }

      num_clients = 2;
      while (num_clients > 0)
        {
          ready = SDLNet_CheckSockets (set, 1000 * 10);
          if (ready < 1)
            {
              printf ("SDLNet_CheckSockets: %s\n", SDLNet_GetError ());
              exit (1);
            }
          else
            {
              printf ("There are %d sockets ready\n", ready);
            }

          if (SDLNet_SocketReady (sock_client[0]))
            {
              SDLNet_TCP_Recv (sock_client[0], &player_y[0], sizeof (int));
              //Ausgabe der Daten
              printf ("\tReceive-%d_X  %d\n", 0, player_x[0]);
              num_clients = SDLNet_TCP_DelSocket (set, sock_client[0]);
            }

          if (SDLNet_SocketReady (sock_client[1]))
            {
              SDLNet_TCP_Recv (sock_client[1], &player_y[1], sizeof (int));
              //Ausgabe der Daten
              printf ("\tReceive-%d_X  %d\n", 1, player_x[1]);
              num_clients = SDLNet_TCP_DelSocket (set, sock_client[1]);
            }
        } /* while */

      /* Aufräumen */
      SDLNet_FreeSocketSet (set);
      SDLNet_TCP_Close (sock_server);
      SDLNet_TCP_Close (sock_client[0]);
      SDLNet_TCP_Close (sock_client[1]);
    }
  else
    {
      printf ("...sorry!\n");
    }
  return 0;
}


Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Alexander,

was heisst "abstürzen"? Warscheinlich hängt er nur in einem 
blockierendem Socket.
Mach dich mal schlau über blockierende/nicht blockierende Sockets.

Und über das Socket-Komando select gleich mit. Ohne diesen wirst du 
nicht dein Ziel erreichen können.

Warum benutzt du eine SDL(???)-Libery und nicht die eingebauten Sockets?
z.B. WinSocket2.

Liegen alle Clients in einem Netzwerk (Broadcast-Domäne)?
Wenn Ja: Dann könnte man Dein Problem ohne Server lösen, in dem man 
UDP-Broadcast verwendet.  Ist eine Grössenordnung einfacher zu 
programmieren, aber auch nicht trivial, wenn es "Wasserdicht" sein soll.


ich hoffe, ich konnte dir ein paar Anregungen geben.

Volker

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Ljubizki schrieb:
> num_clients = 2;

erscheint mir komisch... vorallem weil du vorher ++ gemacht hast

Autor: Halgn H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Volker Zabe schrieb:
> Hallo Alexander,
>
> was heisst "abstürzen"? Warscheinlich hängt er nur in einem
> blockierendem Socket.
> Mach dich mal schlau über blockierende/nicht blockierende Sockets.
>
> Und über das Socket-Komando select gleich mit. Ohne diesen wirst du
> nicht dein Ziel erreichen können.
Mh du meinst:
sock_client[client ID]
das kenn ich schon^^

>
> Warum benutzt du eine SDL(???)-Libery und nicht die eingebauten Sockets?
> z.B. WinSocket2.
Weil ich es für Linux, Mac und windows mache.(SDL_Net)
>
> Liegen alle Clients in einem Netzwerk (Broadcast-Domäne)?
> Wenn Ja: Dann könnte man Dein Problem ohne Server lösen, in dem man
> UDP-Broadcast verwendet.  Ist eine Grössenordnung einfacher zu
> programmieren, aber auch nicht trivial, wenn es "Wasserdicht" sein soll.
Es soll für JEDEN erreichbar sein. (Das ist nicht das probelm... da muss 
ich nur ein wert ändern und dan ist es überall erreichbar^^)

>
>
> ich hoffe, ich konnte dir ein paar Anregungen geben.
>
> Volker
Danke aber ich bleib bei SDL gründe:
- für fast alle Betriebsysteme
- sehr leicht
- viele tutorials
- viele erweiterungen

Mfg NightAlex

Autor: Drehwurm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Ljubizki schrieb:
> Danke aber ich bleib bei SDL

Spricht ja nichts dagegen.

Was deinem Server noch fehlt ist die möglichkeit mehrere Sockets 
(Clients) gleichzeitig zu bedienen.
Das geht entweder über einen Thread pro socket, oder über select/poll 
o.Ä.

SDL_net kapselt das select-gewurschtel auch schön weg, schau mal die 
Doku durch.
Hinweise:

Einmal mit
SDLNet_AllocSocketSet
ein Socket Set anlegen. Ist sozusagen ein Array zum verwalten der 
offenen Verbindungen.

Nach jedem SDLNet_accept das neue Client-Socket mit:
SDLNet_AddSocket
zum Set hinzufügen.

SDLNet_DelSocket bei Disconnect/Error.

SDLNet_CheckSockets dann in deiner Haupt-Schleife, um auf Aktivität auf 
den Sockets zu warten.

Soweit verstanden?

Dann schau mal hier:
http://www.libsdl.org/projects/docs/SDL_net/demos/
"tcpmultiserver.c" und "tcpmulticlient.c" ist was du suchst.

Viel Erfolg.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.