Advertisement

Detect Lan game server

Started by May 21, 2001 09:41 AM
10 comments, last by wedgeboy 23 years, 8 months ago
hello.. currently i m develop a lan game which consist of client/server architecture.. i would like to implement my client side which able to detect all the LAN game servers whcih all are online....how do i implement the client side so that it can broadcast a query packet to all the LAN game server without know what the LAN game server ip add? for example, half life counterstrike LAN game, it able to refresh the LAN game list...and all the game server will appear on the list... how to implement this kind of service?
The most simplistic way to detect a server is to use UDP datagram broadcasting. Broadcasting is the act of sending a datagram packet to every machine on the LAN. While routers typically do not propagate (i.e. forward) broadcast packets, ever LAN machine on the same subnet should receive the broadcast. Basically the client broadcasts a UDP datagram packet to a specified port and any servers on the LAN network will respond.

So how do you do it? The following is something I've just thrown together off the top of my head. I can't guarantee it will work but should give you the general idea.

-------------------

First we will be a simple server. Error checking is minimal and it doesn't close sockets or cleanup Winsock.

  #include <winsock2.h>typedef struct tagSERVER_QUERY{        unsigned long  filters;} SERVER_QUERY, *PSERVER_QUERY;typedef struct tagSERVER_INFO{        unsigned char  servernamelen;    unsigned char* servername;    unsigned long  ip;    unsigned short port;      unsigned char  maxplayers;    unsigned char  gametype;     unsigned char  passwordrequired;} SERVER_INFO, *PSERVER_INFO;int main(){        WSADATA wsadata;    // startup Winsock    if(WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)        return 1;  // an error occurred    SOCKET server_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if(server_socket == INVALID_SOCKET)        return 1;  // an error occurred    sockaddr_in serveraddr;            serveraddr.sin_family      = AF_INET;    serveraddr.sin_port        = htons(19255);    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);    if(bind(server_socket, (sockaddr*)&serveraddr, sizeof(serveraddr)) == SOCKET_ERROR)        return 1;  // an error occurred    sockaddr_in recv_addr;        int         recv_addrlen = sizeof(recv_addr);    char        recv_buffer[100],                send_buffer[100];    int result = 0;    // fill our SERVER_INFO data        SERVER_INFO serverinfo;        GetServerInfo(serverinfo);        PutServerInfo(send_buffer, serverinfo);    SERVER_QUERY query;    while(1)        {                result = recvfrom(server_socket,                          recv_buffer,                          100,                          0,                          (sockaddr*)&recv_addr,                          &recv_addrlen);       if(result == SOCKET_ERROR)                        return 1;        // get query from recv_buffer       GetQueryInfo(query, recv_buffer, result);              // we've received some query packet, so respond in       // kind with our information.       result = sendto(server_socket,                       send_buffer,                       100,                       0,                       (sockaddr*)&recv_addr,                        recv_addrlen);       if(result == SOCKET_ERROR)             return 1;  // an error occurred    }    return 0;}  


Now we do the client.

  #include <winsock2.h>typedef struct tagSERVER_QUERY{    unsigned long  filters;} SERVER_QUERY, *PSERVER_QUERY;typedef struct tagSERVER_INFO{    unsigned char  servernamelen;    unsigned char* servername;        unsigned long  ip;    unsigned short port;    unsigned char  maxplayers;    unsigned char  gametype;    unsigned char  passwordrequired;} SERVER_INFO, *PSERVER_INFO;int main(){    WSADATA wsadata;        // startup Winsock    if(WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)        return 1;  // an error occurred    SOCKET client_socket = socket(AF_INET, SOCK_DGRAM, 0);    if(client_socket == INVALID_SOCKET)        return 1;  // an error occurred        // put the socket into broadcast mode    BOOL broadcast = TRUE;    setsockopt(client_socket, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(BOOL));	sockaddr_in clientaddr,	            serveraddr;    clientaddr.sin_family           = AF_INET;    clientaddr.sin_port             = htons(0);    clientaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);    int result = 0;    result = bind(client_socket, (sockaddr*)&clientaddr, sizeof(clientaddr));    if(result == SOCKET_ERROR)	return result = WSAGetLastError();    sockaddr_in recv_addr;    int         recv_addrlen = sizeof(recv_addr);    char        recv_buffer[100],                send_buffer[100];    SERVER_QUERY query;    SERVER_INFO  server_info;    MakeQuery(query, send_buffer);    serveraddr.sin_family           = AF_INET;    serveraddr.sin_port             = htons(19255);    serveraddr.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);    result = sendto(client_socket,                    send_buffer,                    100,                    0,                    (sockaddr*)&serveraddr,                    sizeof(serveraddr));        if(result == SOCKET_ERROR)        return result = WSAGetLastError();	// receive query results - one result will be received for each running server    while(1)    {        result = recvfrom(client_socket,                          recv_buffer,                          100,                          0,                          (sockaddr*)&recv_addr,                          &recv_addrlen);        if(result == SOCKET_ERROR)            return result = WSAGetLastError();        GetServerInfoFromBuffer(serverinfo, recv_buffer, result);        WriteServerInfo(serverinfo);    }        return 0;          }  


A few of the functions are not shown here but I'm sure you can figure out what they should do (I didn't feel like writing them here). To get this code to compile, you must define the missing functions, or just comment them out. The sending and receiving functions are not optmized as there is no need to send 100 bytes everytime. It is just a lazy way for me write the code quickly

Hopefully this works. I'll copy the code and test it out and make any changes if I discover any areas. Still, hopefully this points you in the correct direction.

Best regards and good luck,

Dire Wolf
www.digitalfiends.com

Edited by - Dire.Wolf on May 21, 2001 2:49:45 PM
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Advertisement
Try reading up on IP Multicasting. This may be what your after.
I''ve discovered a couple errors in the above code. Give me a few minutes and I''ll have it fixed



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
The code has been fixed (see above).

Let me know if you have any more questions.

Dire Wolf
www.digitalfiends.com

Edited by - Dire.Wolf on May 21, 2001 2:42:02 PM
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Multicasting is extremely useful in reducing network bandwidth consumption when compared to broadcasting packets. Querying for LAN game servers is not something I''d consider extremely data intensive so I wouldn''t worry about that. Now, if you are trying to stream video information to a number of clients I would not use pure broadcasting; this is were multicasting comes in handy.

I still think simple broadcasting is the way to go for what you need.



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Advertisement
thanks dire wolf...your idea and advise are certainly help ful...but i got one big problem...that i doing my lan game in VB...i m true sorry that i forgot stated in here...sorry
In the immortal words of Homer Simpson:

DOH

You can still use the idea in VB. You just need to create a whole bunch of declare function imports in a .bas file. Go to www.allapi.net and download the API Guide and Toolshed (1.99MB). Then search for the socket() function using the API-Guide program. It will show you how to use API commands in VB.



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
If I remember correctly, if you wanted to broadcast to all the computers on a LAN using TCP/IP then you should send the data to the IP address 192.168.0.255 But you might want to check this out first as im not entirely sure. Anybody know?
I think the broadcast address was 192.168.0.0, but it could be that both are used as broadcast addresses.

Coder10000

This topic is closed to new replies.

Advertisement