gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > DS-Wifi Question

#169045 - DarkShadow44 - Wed Jun 10, 2009 9:11 pm

Hello,
I want to create a game using a wifi connection, but I can only create a socket on a server.
Do I need an own server to use wifi connection ?

And can I create more than one socket on one server ?

Thanks for your help in advance !

#169049 - melw - Thu Jun 11, 2009 12:16 pm

It definitely helps if you have an own server or shell access to one, at least during the development. If you plan to create something that's easily installed elsewhere, better stick to Linux (same code works with some tweaking also on Macs).

On the socket coding in general, there's several tutorials floating around in the internet - here's one page straight from Google: http://www.linuxhowtos.org/C_C++/socket.htm

#169052 - DarkShadow44 - Thu Jun 11, 2009 4:56 pm

So DO i have to use an own server or not ?

And can a DS (as Server) can send something like a broadcast message that it exists ? (I mean a specific string which contains the IP and the Name of the Game...)

#169053 - elhobbs - Thu Jun 11, 2009 5:24 pm

It depends on what you are trying to do.

a server is just an application that listens for connections on defined ports and accepts connection requests and then responds according to the nature of the service(s) that it provides.

a file server - serves files
a web server - serves web pages
a sql server - serves datasets based on structured query language requests

this is a very simplistic view, but it should point you in the right direction.

you have a couple basic options
1) the server application resides on a pc and the ds(s) or other pc(s) are the clients
2) one ds is the server and other ds(s) or pc(s) can connect as clients

so what exactly do you mean by "I can only create a socket on a server"?

probably your best bet is to read up a little bit about tcp/ip sockets as suggested in the previous post.

#169054 - DarkShadow44 - Thu Jun 11, 2009 5:41 pm

I searched for sockets in C/C++ with google, but most were only for windows server, not for the DS. They use librarys the DS can't use.

I want to create a wifi game, and the best would be that you can choose "Host" or "Join".

Is it possible to set these DS ("Hosts") as servers and the others can search them ? (Like I said with a broadcast?)

Else, how can I use a windows program to connect all these DS as I said ? (Clients search Hosts)
Would I need an PC as server to search all players ?

Maybe later I want to add online highscores or map downloading, but there I MUST use a PC as server, or not ?

#169055 - elhobbs - Thu Jun 11, 2009 5:57 pm

look at berkeley sockets examples. the dswifi library provides this interface.

look at the dswifi examples

look at other ds source code that uses wifi.

you could even take a look at the cquake source code (a ds port of idsoftware's quake) which implements a client/server architecture. very little in the network codebase needed to be changed to port it to the ds - mostly just the library startup routines.

#169056 - DarkShadow44 - Thu Jun 11, 2009 6:29 pm

OK, but my main problem is:
How can a client search for all maching servers ?
Is it possible for the DS to do a broadcast witch a specific string containing it's IP ? If yes, how ?

The examples only explain searching for APs, connecting and downloading...

#169059 - elhobbs - Thu Jun 11, 2009 7:41 pm

I am guessing you did not look at the source code to quake or cquake.

one solution is for clients to send broadcast UDP messages (hint SO_BROADCAST) that your server should respond to if it is accepting new connections. the reponse could contain the information needed to connect (ip address, port, etc). this solution could be used to find all hosts on your subnet and requires no infrastructure.

#169062 - DarkShadow44 - Thu Jun 11, 2009 8:34 pm

Sorry, but....

What do you mean with "subnet and requires no infrastructure" ?
I want to play via the internet...

And where should I create socket ? On the clients DS ?

Maybe you can post an example code (sorry but...)

#169063 - Pete_Lockwood - Thu Jun 11, 2009 8:52 pm

So what you mean is you want someone to do all the work for you?
_________________
It's not an illusion, it just looks like one.

#169064 - DarkShadow44 - Thu Jun 11, 2009 9:02 pm

No, but I want to have answered these questions:

Quote:
What do you mean with "subnet and requires no infrastructure" ?
I want to play via the internet...

And where should I create socket ? On the clients DS ?


Please ?

#169065 - elhobbs - Thu Jun 11, 2009 9:19 pm

you really, really, really need to read up as to what a socket is.

once you know what a socket is then come back and ask a more specific question.

you may find that if you put forth no effort on your own, and keep ignoring advice, that people will not be so inclined to help you

#169075 - DarkShadow44 - Fri Jun 12, 2009 4:52 pm

Hello, I've read some tutorials
Quote:
look at berkeley sockets examples. the dswifi library provides this interface.

Quote:
to send broadcast UDP messages (hint SO_BROADCAST)

@ elhobbs: Thanks for that ideas, really helped me


and I managed it to send AND receive a broadcast, but I only works if the server started first. If the server later comes, he recevies nothing.

Can you guess why ? The client sends and the server listens...

If I want receive the broadcast more than 32 times it also hangs (should be no problem, but would be good to know why...)

And why can't I use recv() instead of recvfrom() ?

And can I add a kind of TIMEOUT for recvfrom if I don't know how many Players will play (without editing the dswifi lib) ?


P.S. Please tell me if these answers obvious, but I couldn't find it out (but I will keep trying)


Code:
int ServerSockListen;
int ClientSockSend;
int main()
{
   consoleDemoInit();
 
   iprintf("\x1b[1;1HStart");
 
   Wifi_InitDefault(WFC_CONNECT);
 
 
 
   while(1)
   {
      iprintf("\x1b[5;1HPress A for Server, B for Client");
      
      scanKeys();
      
      if(keysDown() & KEY_A)
      {
         server=true;
         break;
      }
      
      if(keysDown() & KEY_B)
      {
         server=false;
         break;
      }
      swiWaitForVBlank();
   }
 
    iprintf("\x1b[7;1HLoading");
   struct sockaddr_in i_addr;
   i_addr.sin_family = AF_INET;
   i_addr.sin_port = htons(6666);
   i_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
   
   
   int optval = 1;
   
   if(server)
   {
      ServerSockListen=socket(AF_INET, SOCK_DGRAM, 0);
      
      bind(ServerSockListen, (struct sockaddr *) &i_addr, sizeof(i_addr));
      
      
      int i=0;
      while(1)
      {
         char buffer[8];
         int size=sizeof(struct sockaddr);

         recvfrom(ServerSockListen,buffer,8,0, (struct sockaddr *) &i_addr, &size);

         iprintf("\x1b[9;1HWaiting:%d ",i);
         
         if(buffer[0]=='P' && buffer[1]=='A')
         {
            iprintf("\x1b[11;1HReceived: %s ",buffer);
         }
         i++;
         swiWaitForVBlank();
      }
   }
   else
   {
      int i=0;
      while(1)
      {
         ClientSockSend=socket(AF_INET, SOCK_DGRAM, 0);
         
         
         setsockopt(ClientSockSend,SOL_SOCKET,SO_BROADCAST,&optval,sizeof(int));
      
         sendto(ClientSockSend,"PALIB-HI",8,0, (struct sockaddr *) &i_addr, sizeof(i_addr));
         
         iprintf("\x1b[9;1HSending:%d ",i);
         i++;
         swiWaitForVBlank();
      }
   }
   
   

   iprintf("\x1b[22;1HEntering main loop...");
    
   while(1)
   {
      swiWaitForVBlank();
   }
   
   return 0;
}

#169078 - elhobbs - Sat Jun 13, 2009 12:21 am

recv only works on a connected socket. recvfrom can be used with unconnected sockets - it has extra parameters to record who it is from.

not sure why it crashes at exactly 32 iterations but you have a buffer overflow when you print the received packet. your string is 9 chars in length including the null terminator. since you are only sending 8 chars your are not getting a null terminated string. iprintf expects a null terminated string.

you probably want to take a look at FIONBIO to set your sockets to non-blocking.

#169083 - DarkShadow44 - Sat Jun 13, 2009 4:08 pm

Quote:
you have a buffer overflow when you print the received packet. your string is 9 chars in length including the null terminator. since you are only sending 8 chars your are not getting a null terminated string. iprintf expects a null terminated string.


Thanks. That explains, why I outputs one more, unreadable char!