Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Game Server Scanner

0.00/5 (No votes)
22 Aug 2004 1  
Port scanner to find game servers on a LAN.

Screenshot

Sample Image - gfxscan.jpg

Introduction

gfxscan is a simple port scanner developed to search for remote computers on LAN running game servers.

It sends simple UDP request asynchronously to all the IPSs on a particular port in a subnet. The port being 27015 in case of counter strike. The response is then parsed to get the details of the server. There are many additional requests which can be made to know more about the game, which I will be posting later.

I tried to find a simple port scanner for LAN and Googled a lot, but didn't find any. So I decided to write my own game server scanner.

Problems Faced

Major problem was to reduce the time wait for a read call. I got rid of it by setting option System::Net::Sockets::SocketOptionName::ReceiveTimeout as 1000.

sock->SetSocketOption(System::Net::Sockets::SocketOptionLevel::Socket, 
      System::Net::Sockets::SocketOptionName::ReceiveTimeout,1000);

The blocking nature of a socket can be nulled using sock->set_Blocking(false).

Major Code Fragments

  1. Creating a UDP socket, starting a new thread to read for the response from hosts if found a server, and sending UDP requests to hosts in a subnet:
    void scanServers(String* ip[],int prt,int count)
    {
      boolRead =1;
      port = prt;
      sock = new Socket(AddressFamily::InterNetwork, 
                 SocketType::Dgram,ProtocolType::Udp);
      readThread = new Thread(new ThreadStart(this,read));
      readThread->Start();
      Byte msg[]= System::Text::Encoding::ASCII->GetBytes("xxxxinfo\0");
      Byte msg2[]= new Byte[1000];
      msg[0] = 0xff;
      msg[1] = 0xff;
      msg[2] = 0xff;
      msg[3] = 0xff;
      for(int i=0;i<count;i++)
      {
        IPAddress* ipAdd = IPAddress::Parse(ip->GetValue(i)->ToString());
        IPEndPoint* endPoint = new IPEndPoint(ipAdd,port);
        EndPoint* senderRemote = __try_cast<EndPoint*>(endPoint);
        try
        {
          sock->SendTo(msg, 0, msg->Length, SocketFlags::None, endPoint);
        }
        catch ( SocketException* se )
        {
          //MessageBox::Show(se->Message,"exception while sending",
    
               MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
        }
      }
    }
  2. Setting the non-blocking and time wait options, reading from hosts on the same socket, decoding the message, and then sending it to display the message correctly:
    void read()
    {
      IPEndPoint* sender = new IPEndPoint(IPAddress::Any, port);
      EndPoint* senderRemote = __try_cast<EndPoint*>(sender);
      Byte msg2[]= new Byte[1000];
      sock->set_Blocking(false);
      sock->SetSocketOption(System::Net::Sockets::SocketOptionLevel::Socket,
               System::Net::Sockets::SocketOptionName::ReceiveTimeout,1000);
    
      while(boolRead==1)
      {
        try 
        {
          int iR = sock->ReceiveFrom(msg2, 0, msg2->Length, 
                        SocketFlags::None, &senderRemote);
          Char chars[] = new Char[2000];
          Decoder* d = Encoding::UTF8->GetDecoder();
          int charLen = d->GetChars(msg2, 0, msg2->Length, chars, 0);
          String* str = new String(chars); 
          parseAndAdd(str);
        }
        catch (SocketException* se)
        {
          MessageBox::Show(se->Message,"exception while sending", 
                  MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
        }
      }
      this->labelStatus->set_Text(new String("Scan Complete."));
      this->labelStatus->Invalidate();
    }

I am looking forward to making a class to provide a neat interface to find game servers on LAN, and to ping them for more information of the game, like no. of players, map being played, and status of each player.

Happy Gaming till then :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here