SDL Net Server

Gast #1911030
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
1
#include <SDL/SDL.h>
2
#include <SDL/SDL_net.h>
3
#include <stdlib.h>
4
#include <stdio.h>
5

6
int player_x[50];
7
int player_y[50];
8

9
int main ( int argc, char** argv )
10
{
11
  IPaddress address;
12
  TCPsocket sock_server, sock_client[50];
13
  SDLNet_SocketSet set;
14
  int wait, num_clients, data, ready;
15

16

17
  if(SDL_Init (0) ==-1)
18
    {
19
      printf ("SDL_Init: %s\n", SDL_GetError ());
20
      exit (1);
21
    }
22
  if(SDLNet_Init () ==-1)
23
    {
24
      printf ("SDLNet_Init: %s\n", SDLNet_GetError ());
25
      exit(1);
26
    }
27
  if (SDLNet_ResolveHost (&address, NULL, 10000) == -1)
28
    {
29
      printf ("SDLNet_ResolveHost: %s\n", SDLNet_GetError ());
30
      SDLNet_Quit ();
31
      exit (1);
32
    }
33
  sock_server = SDLNet_TCP_Open (&address);
34
  if (!sock_server)
35
    {
36
      printf ("SDLNet_TCP_Open: %s\n", SDLNet_GetError ());
37
      SDLNet_Quit ();
38
      exit (1);
39
    }
40

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

43
  wait = 10;
44
  num_clients = 0;
45
  do
46
    {
47
      SDL_Delay (1000);
48
      sock_client[num_clients] = SDLNet_TCP_Accept (sock_server);
49
      if (sock_client[num_clients])
50
        {
51
          printf ("accepted %d\n", num_clients + 1);
52
          num_clients++;
53
        }
54
      wait--;
55
    } while ((num_clients < 50) && (wait > 0));
56

57
  if (wait > 0)
58
    {
59
      /* Jetzt haben wir Clients */
60

61
      /* Platz für Sockets machen*/
62
      set = SDLNet_AllocSocketSet (50);
63
      if (!set)
64
        {
65
          printf ("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError ());
66
          exit (1);
67
        }
68
      SDLNet_TCP_AddSocket (set, sock_client[0]);
69
      if (SDLNet_TCP_AddSocket (set, sock_client[1]) != 2)
70
        {
71
          printf ("SDLNet_TCP_AddSocket: %s\n", SDLNet_GetError ());
72
          exit (1);
73
        }
74

75
      num_clients = 2;
76
      while (num_clients > 0)
77
        {
78
          ready = SDLNet_CheckSockets (set, 1000 * 10);
79
          if (ready < 1)
80
            {
81
              printf ("SDLNet_CheckSockets: %s\n", SDLNet_GetError ());
82
              exit (1);
83
            }
84
          else
85
            {
86
              printf ("There are %d sockets ready\n", ready);
87
            }
88

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

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

106
      /* Aufräumen */
107
      SDLNet_FreeSocketSet (set);
108
      SDLNet_TCP_Close (sock_server);
109
      SDLNet_TCP_Close (sock_client[0]);
110
      SDLNet_TCP_Close (sock_client[1]);
111
    }
112
  else
113
    {
114
      printf ("...sorry!\n");
115
    }
116
  return 0;
117
}
#1913307
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
Gast #1913537
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
Gast #1913583
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren