[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