Thread: Best way to handle incoming commands from a client.

  1. #1
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320

    Best way to handle incoming commands from a client.

    My current idea for this would be to have a function inside my class that contains the socket that looks something like this:
    My question is "Can it be done better?" I would hope to keep my input as a string but that could change as well the lagg times killed my last mmorpg attempt.
    Code:
    void VAA_Input(char* Command)  //validate and act on input
    {
       switch(Command[0])
       {
          case 'a':
          case 'A':
          if(strncmp(Command,"Aquire_Item",11) == 0)
          {
              //run code to aquire specified item
          }else
          if(strcmp ...)
          {
              //do something
          }else
          break;
          .
          .
          .
          case 'z':
          case Z':
    
          break;
          default:    
          //ignore it because it isn't a keyword
          break;
       }
    }

  2. #2
    Registered User Osaou's Avatar
    Join Date
    Nov 2004
    Location
    Stockholm, Sweden
    Posts
    69
    Sure, but I'd use shorter commands... either "AI" or "AqIt"... That way you can cast it to an int * and just test for a single value... =)
    And it will be less lag prone...
    Last edited by Osaou; 07-25-2006 at 09:27 AM.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    What a horrid solution.
    If you're only pointing at two chars (and a \0), then the 4th byte is undefined and you'll never match it with your int comparison.
    Not to mention the possibility of bus errors caused by mis-aligned pointers.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ASIZE(x)  ((sizeof(x))/(sizeof(x[0])))
    
    /* Stuff to do */
    void add ( void ) {
      printf( "Hello from add\n" );
    }
    void edit ( void ) {
      printf( "Hello from edit\n" );
    }
    void delete ( void ) {
      printf( "Hello from delete\n" );
    }
    
    /* A table of commands and actions */
    struct table_tag {
      char    *cmd;
      void    (*fn)(void);
    } table[] = {
      { "add",    add },
      { "edit",   edit },
      { "delete", delete },
    };
    
    int comp ( const void *a, const void *b ) {
      const struct table_tag  *pa = a;
      const struct table_tag  *pb = b;
      return strcmp ( pa->cmd, pb->cmd );
    }
    /* Find a function, given a command */
    void searchCommand ( char *cmd ) {
      struct table_tag search = { cmd, 0 };
      struct table_tag *ans;
      ans = bsearch ( &search,
                      table, ASIZE(table), sizeof(table[0]),
                      comp );
      if ( ans ) {
        ans->fn();  /* Do it! */
      } else {
        printf( "%s not found\n", cmd );
      }
    }
    
    int main ( ) {
      /* Ensure it's sorted, for bsearch to work */
      qsort ( table, ASIZE(table), sizeof(table[0]), comp );
    
      /* Practice commands */
      searchCommand( "edit" );
      searchCommand( "exit" );
    
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User Osaou's Avatar
    Join Date
    Nov 2004
    Location
    Stockholm, Sweden
    Posts
    69
    Salem, I never said anything about zero-termination... and when I said he could cast it to an int I was ofcourse referring to the 4-byte version... /blatant defending

  5. #5
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    The messages will be formatted on the client side so the server knows what to expect. My reasoning for checking the first letter is to keep from having a ungodly long if(){}elseif grouping from hell. It seemed to me that a switch statement could cut down on my checking times(untested) it just seems logical. There would also be a high priority(top of the list) character IMO for things that need to happen as quickly as possible IE combat.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > There would also be a high priority(top of the list) character IMO for things that need to happen as quickly as possible IE combat.
    Time for a maths lesson.

    Take a super idealised network with 8Mbit / sec bandwidth, which is all for you.
    Theoretical limit 1Mbyte / second or 1uS for each byte.
    Or several thousand instructions on your average desktop PC.

    Say you want to send a 4-byte command via UDP
    4 + 8 (UDP Header) + 24 (IP header) = 36 bytes.
    So that's 36uS (or ~100K instructions) just to send the message on an ideal network.
    That's ignoring any additional information which the underlying transport applies to the data.

    Now factor in that most people don't have that kind of link. Even at it's best, my broadband is only rated at 2MBit/Sec (25% of the ideal). If it halves again because of general business of everyone else using the network, we're looking at ~10% of the super-ideal case.
    Now we're looking at 100's of uS to send just one short message and millions of instructions on your processor bumming around waiting for the next thing to do.

    My suggestion is you'd better make sure you're optimising the right thing before embarking on producing some f-ugly code in the belief it will speed things up for you. The time taken to decide what to do (compare some characters) is usually pretty minimal compared to the work done as a consequence (redraw a 1024x768 frame buffer).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    If you simply want a nice structure for matching commands, I recommend you look into tries. A trie is a tree-like structure specialized for matching strings and used e.g. in dictionaries. One of the nice things is that it allows you to perform shortest unambiguous input matching, i.e. the user can enter only the first few letters of a command if no other command starts with those same letters.
    For example, if your program has take commands "pick" (pick up), "go", "talk", "push" and "pull", you can use "g" for "go" and "t" for "talk", but you need "pi" for "pick" ("p" is ambiguous), "pus" for "push" and "pul" for "pull". Of course, you may always write more than strictly necessary, up to the full command.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting other processes class names
    By Hawkin in forum Windows Programming
    Replies: 3
    Last Post: 03-20-2008, 04:02 PM
  2. Socket Programming Problem!!!!
    By bobthebullet990 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-21-2008, 07:36 PM
  3. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  4. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  5. any way to get or find a window client are handle and capture it?
    By shukisnike in forum Windows Programming
    Replies: 1
    Last Post: 12-21-2005, 06:42 PM