[Tux4kids-commits] r1264 - in tuxmath/branches/lan: server src

David Bruce dbruce-guest at alioth.debian.org
Fri Jul 24 09:34:34 UTC 2009


Author: dbruce-guest
Date: 2009-07-24 09:34:31 +0000 (Fri, 24 Jul 2009)
New Revision: 1264

Modified:
   tuxmath/branches/lan/server/server.c
   tuxmath/branches/lan/server/testclient.c
   tuxmath/branches/lan/server/transtruct.h
   tuxmath/branches/lan/src/network.c
Log:
start of udp code for server autodetection



Modified: tuxmath/branches/lan/server/server.c
===================================================================
--- tuxmath/branches/lan/server/server.c	2009-07-23 21:57:47 UTC (rev 1263)
+++ tuxmath/branches/lan/server/server.c	2009-07-24 09:34:31 UTC (rev 1264)
@@ -39,6 +39,7 @@
 void cleanup_server(void);
 
 // top level functions in main loop:
+void check_UDP(void);
 void update_clients(void);
 int check_messages(void);
 
@@ -48,8 +49,8 @@
 void check_game_clients(void);
 
 // message reception:
-int handle_client_game_msg(int i,char *buffer);
-void handle_client_nongame_msg(int i,char *buffer);
+int handle_client_game_msg(int i, char* buffer);
+void handle_client_nongame_msg(int i, char* buffer);
 int msg_set_name(int i, char* buf);
 void start_game(int i);
 void game_msg_correct_answer(int i, char* inbuf);
@@ -81,7 +82,8 @@
 
 
 /*  ------------   "Local globals" for server.c: ----------  */
-TCPsocket server_sock = NULL; /* Socket descriptor for server            */
+UDPsocket udpsock = NULL;     /* Used to listen for client's server autodetection          */
+TCPsocket server_sock = NULL; /* Socket descriptor for server to accept client TCP sockets. */
 IPaddress ip;
 SDLNet_SocketSet client_set = NULL, temp_sock = NULL, temp_set = NULL;
 static client_type client[MAX_CLIENTS];
@@ -110,7 +112,8 @@
   /*    ------------- Main server loop:  ------------------   */
   while (!quit)
   {
-
+    /* Respond to any clients pinging us to find the server: */
+    check_UDP();
     /* Now we check to see if anyone is trying to connect. */
     update_clients();
     /* Check for any pending messages from clients already connected: */
@@ -159,6 +162,12 @@
     return 0;
   }
 
+  if(SDL_Init(0)==-1)
+  {
+    printf("SDL_Init: %s\n", SDL_GetError());
+    return 0;;
+  }
+
       
   if (SDLNet_Init() < 0)
   {
@@ -186,7 +195,15 @@
     printf("SDLNet_AllocSocketSet: %s\n", SDLNet_GetError());
     return 0;
   }
- return 1;
+
+  //Now open a UDP socket to listen for clients broadcasting to find the server:
+  udpsock = SDLNet_UDP_Open(DEFAULT_PORT);
+  if(!udpsock)
+  {
+    printf("SDLNet_UDP_Open: %s\n", SDLNet_GetError());
+    exit(2);
+  }
+  return 1;
 }
 
 
@@ -229,9 +246,30 @@
 
 // ----------- Top level functions in main loop ---------------:
 
+//check_UDP() is the server side of the client-server autodetection system.
+//When a client wants to connect, it sends a UDP broadcast to the local
+//network on this port, and the server sends a response.
+void check_UDP(void)
+{
+  char buf[NET_BUF_LEN];
+  int recvd = 0;
+  UDPpacket* pkt = SDLNet_AllocPacket(NET_BUF_LEN);
+  recvd = SDLNet_UDP_Recv(udpsock, pkt);
+  if(recvd)
+  {
+	printf("UDP Packet incoming\n");
+	printf("\tChan:    %d\n", pkt->channel);
+	printf("\tData:    %s\n", (char *)pkt->data);
+	printf("\tLen:     %d\n", pkt->len);
+	printf("\tMaxlen:  %d\n", pkt->maxlen);
+	printf("\tStatus:  %d\n", pkt->status);
+	printf("\tAddress: %x %x\n", pkt->address.host, pkt->address.port);
+  }
+}
 
 
 
+
 //update_clients() sees if anyone is trying to connect, and connects if a slot
 //is open and the game is not in progress. The purpose is to make sure our
 //client set accurately reflects the current state.
@@ -371,6 +409,8 @@
     // check all sockets with SDLNet_SocketReady and handle the active ones.
     // NOTE we have to check all the slots in the set because
     // the set will become discontinuous if someone disconnects
+    // NOTE this will only pick up the first message for each socket each time
+    // check_messages() called - probably OK if we just get it next time through.
     for(i = 0; i < MAX_CLIENTS; i++)
     {
       if((client[i].sock != NULL)
@@ -407,12 +447,12 @@
     // Make sure all the active sockets reported by SDLNet_CheckSockets()
     // are accounted for:
 
-    if(actives != ready_found )
+    if(actives > ready_found)
     {
       printf("Warning: SDLNet_CheckSockets() reported %d active sockets,\n"
              "but only %d detected by SDLNet_SocketReady()\n", actives, ready_found);
       //Presently, this just runs ping_client() on all the sockets:
-      test_connections();
+      //test_connections();
     }
   } 
 }
@@ -460,6 +500,9 @@
 // TODO this is not very sophisticated, and only supports one game at a time.
 // We may want to make this extensible to multiple simultaneous games, perhaps
 // with each game in its own thread with its own socket set and mathcards instance.
+// FIXME we need to do more than just toggle game_in_progress - should have
+// start_game() and end_game() functions that make sure mathcards is 
+// properly set up or cleaned up.
 void check_game_clients(void)
 {
   int i = 0;
@@ -487,6 +530,8 @@
   }
   //If the game hasn't started yet, we only start it 
   //if all connected clients are ready:
+  //FIXME should add a timeout so the game eventually starts without
+  //those who don't answer
   else
   {
     int someone_connected = 0;
@@ -733,10 +778,8 @@
   client[i].game_ready = 1; // Means this player is ready to start game
 
 
-  /* FIXME this relies on the server blocking on receive until it gets a    */
-  /* message from each connected client - we should get all our messages    */
-  /* in check_messages()                                                    */
   /*This loop sees that the game starts only when all the players are ready */
+  /* i.e. if someone is connected but not ready, we return.                 */
   for(j = 0; j < MAX_CLIENTS; j++)
   {
     // Only check sockets that aren't null:
@@ -779,7 +822,7 @@
   game_in_progress = 1;
 
 
-  /* Send enough questions to fill the initial comet slots (currently 4): */
+  /* Send enough questions to fill the initial comet slots (currently 10) */
   for(j = 0; j < TEST_COMETS; j++)
   {
     int k = 0;

Modified: tuxmath/branches/lan/server/testclient.c
===================================================================
--- tuxmath/branches/lan/server/testclient.c	2009-07-23 21:57:47 UTC (rev 1263)
+++ tuxmath/branches/lan/server/testclient.c	2009-07-24 09:34:31 UTC (rev 1264)
@@ -72,6 +72,7 @@
       erase_flashcard(&comets[i]);
   }
 
+
   /* Connect to server, create socket set, get player nickname, etc: */
   if(!LAN_Setup(argv[1], DEFAULT_PORT))
   {

Modified: tuxmath/branches/lan/server/transtruct.h
===================================================================
--- tuxmath/branches/lan/server/transtruct.h	2009-07-23 21:57:47 UTC (rev 1263)
+++ tuxmath/branches/lan/server/transtruct.h	2009-07-24 09:34:31 UTC (rev 1264)
@@ -6,7 +6,7 @@
         that would be transferred between the server and the client
         during the multiplayer LAN game.
 
-        Author: David Bruce ,Akash Gangil and the TuxMath team, (C) 2009
+        Author: David Bruce, Akash Gangil and the TuxMath team, (C) 2009
 
         Copyright: See COPYING file that comes with this distribution (briefly, GNU GPL version 2 or later)
 

Modified: tuxmath/branches/lan/src/network.c
===================================================================
--- tuxmath/branches/lan/src/network.c	2009-07-23 21:57:47 UTC (rev 1263)
+++ tuxmath/branches/lan/src/network.c	2009-07-24 09:34:31 UTC (rev 1264)
@@ -26,30 +26,85 @@
 
 TCPsocket sd;           /* Server socket descriptor */
 SDLNet_SocketSet set;
+IPaddress serv_ip;
 
-//MC_FlashCard flash;    //current question
-/*int quit = 0;
-
-int Make_Flashcard(char *buf, MC_FlashCard* fc);
-int LAN_AnsweredCorrectly(MC_FlashCard* fc);
-int playgame(void);
-void server_pinged(void);*/
-
 /* Local function prototypes: */
 int say_to_server(char *statement);
 int evaluate(char *statement);
 
 
+
+int LAN_DetectServers(void)
+{
+  UDPsocket udpsock = NULL;  
+  UDPpacket* out;
+  IPaddress bcast_ip;
+  int sent = 0;
+
+  /* Docs say we are supposed to call SDL_Init() before SDLNet_Init(): */
+  if(SDL_Init(0)==-1)
+  {
+    printf("SDL_Init: %s\n", SDL_GetError());
+    return 0;;
+  }
+
+  /* Initialize SDL_net */
+  if (SDLNet_Init() < 0)
+  {
+    fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
+    exit(EXIT_FAILURE);
+  }
+
+  //NOTE we can't open a UDP socket on the same port if both client
+  //and server are running on the same machine, so for now we let
+  //it be auto-assigned:
+  udpsock = SDLNet_UDP_Open(0);
+  if(!udpsock)
+  {
+    printf("SDLNet_UDP_Open: %s\n", SDLNet_GetError());
+    return 0;
+  }
+  
+  out = SDLNet_AllocPacket(NET_BUF_LEN); 
+  SDLNet_ResolveHost(&bcast_ip, "255.255.255.255", DEFAULT_PORT);
+  out->address.host = bcast_ip.host;
+  out->address.port = bcast_ip.port;
+  sprintf(out->data, "TUXMATH_CLIENT");
+
+	printf("UDP Packet to be sent:\n");
+	printf("\tChan:    %d\n", out->channel);
+	printf("\tData:    %s\n", (char *)out->data);
+	printf("\tLen:     %d\n", out->len);
+	printf("\tMaxlen:  %d\n", out->maxlen);
+	printf("\tStatus:  %d\n", out->status);
+	printf("\tAddress: %x %x\n", out->address.host, out->address.port);
+
+  //Here we will need to send every few seconds until we hear back from server
+  //and get its ip address:
+  sent = SDLNet_UDP_Send(udpsock, -1, out);
+  printf("UDP packets sent to %d addresses\n", sent);
+  SDLNet_FreePacket(out); 
+}
+
+
 int LAN_Setup(char *host, int port)
 {
   IPaddress ip;           /* Server address */
 
+  if(SDL_Init(0)==-1)
+  {
+    printf("SDL_Init: %s\n", SDL_GetError());
+    return 0;;
+  }
+
   if (SDLNet_Init() < 0)
   {
     fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
     return 0;
   } 
- 
+
+  LAN_DetectServers();
+
   /* Resolve the host we are connecting to */
   if (SDLNet_ResolveHost(&ip, host, port) < 0)
   {
@@ -78,6 +133,7 @@
     // perhaps you need to restart the set and make it bigger...
   }
 
+
   return 1;
 }
 
@@ -326,4 +382,3 @@
 
 
 
-




More information about the Tux4kids-commits mailing list