Forum: PC-Programmierung SDL Net Server


von Halgn H. (Gast)


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
}

von Volker Z. (vza)


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

von ... .. (docean) Benutzerseite


Lesenswert?

Alexander Ljubizki schrieb:
> num_clients = 2;

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

von Halgn H. (Gast)


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

von Drehwurm (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.