Herong's Tutorial Notes on Perl - Part B
Dr. Herong Yang, Version 4.11

XML in Client and Server Communication

Part:   1   2 

This chapter describes:

  • Different XML client and server communication models.
  • XML and Socket Communication Example - GameServer.pl
  • XML and Socket Communication Example - GameClient.pl

XML Client and Server Communication Model

Once we know how to work XML strings and hashes, we can now look at how XML technology can be used in client and server communication.

The most primitive way of using XML technology in client and server communication is to write a client program and a server program to send and receive XML messages with TCP socket communication over Internet. The following diagram illustrates how this works:

Client System                         Server System
             XML    |    Internet    |    XML
Client Prog.<--->TCP|<-------------->|TCP<--->Server Prog.

To learn more about TCP socket communication, see the "Socket Communication" chapter of this book.

XML with Socket Communication Example - GameServer.pl

In the following example, I wrote a simple client and server base game application. It's a simple game, in which the server accepts new clients, and holds a number for the client to guess.

The information is exchanged between the client and server in plain XML format, and delivered with plain TCP communication protocol.

Here is the server program, GameServer.pl:

#- GameServer.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   use Socket;
   use XML::Simple;
   $xs = new XML::Simple(keeproot => 1, forcearray => 1);
   $gameID = 0;
   $number = 0;   
   $response = "<s><i>0</i><m>hello</m></s>";
   &runServer;
   exit;
sub runServer {
   open(LOG,">> GameServer.log");
   select(LOG); $|=1;
   open(STDERR, ">&LOG") || die "Die: Setting STDERR to log file";
   open(REC,">> GameServer.rec");
   select(REC); $|=1;
   socket(SOCK,PF_INET,SOCK_STREAM,'tcp');
   bind(SOCK, pack_sockaddr_in("8080", INADDR_ANY));
   listen(SOCK, 1); # can only take one client at a time
   print LOG localtime().": Listening to port 8080\n";
   for (;;) {
      $cAddress = accept(NEWSOCK,SOCK) || die "Error: Accepting: $!";
      ($cPort, $cHost) = unpack_sockaddr_in($cAddress);
      $cHostName = inet_ntoa($cHost);
      print LOG localtime().": Connected with $cHostName at $cPort\n";
      open(STDIN, "+<&NEWSOCK") || die "Die: Setting STDIN to socket";
      open(STDOUT, "+>&NEWSOCK") || die "Die: Setting STDOUT to socket";
      select(STDOUT); $|=1;
      &serve;
      close(STDIN);
      close(STDOUT);
   }
}
sub serve {
   my ($tag,$fin,$msg);
   while (<STDIN>) {
      /<(\w+)>/ && ($tag=$1) unless $tag;
      /<\/$tag>/ && ($fin=$tag) if $tag;
      $msg = $msg.$_;
      last if $fin;
   }
   print REC "$msg\n";
   my $ref = $xs->XMLin($msg);
   if (exists($ref->{c}->[0]->{i})) {
      my $gid = $ref->{c}->[0]->{i}->[0];
      my $num = $ref->{c}->[0]->{n}->[0];
      if ($gid == $gameID) {
         $msg = &oldGame($gid,$num);
      } else {
         $msg = &invalidGame($gid,$num);
      }
   } else {
      $msg = &newGame;
   }
   print STDOUT $msg;
   print REC "$msg\n";
}
sub oldGame {
   my ($gid,$num) = @_;
   my $ref = $xs->XMLin($response);
   my $msg;
   if ($num == $number) {
      $msg = "Congratulations!\n"
         ."I have another number between 0 and 99 for you to guess.";
      $gameID++;
      $number = rand(100);
   } elsif ($num > $number) {
      $msg = "Your guess is too high.\n Please make another quess.";
   } else {
      $msg = "Your guess is too low.\n Please make another quess.";
   }
   $ref->{s}->[0]->{i}->[0] = $gameID;
   $ref->{s}->[0]->{m}->[0] = $msg;
   return $xs->XMLout($ref); 
}
sub newGame {
   $gameID++;
   $number = rand(100);
   my $ref = $xs->XMLin($response);
   $ref->{s}->[0]->{m}->[0] = "Welcome to Game Server!\n"
      ."I have a number between 0 and 99 for you to guess.";
   $ref->{s}->[0]->{i}->[0] = $gameID;
   return $xs->XMLout($ref); 
}
sub invalidGame {
   my ($sid,$num) = @_;
   my $ref = $xs->XMLin($response);
   $ref->{s}->[0]->{m}->[0] = "Sorry. Your game ID doesn't exist.";
   return $xs->XMLout($ref); 
}

(Continued on next part...)

Part:   1   2 

Dr. Herong Yang, updated in 2006
Herong's Tutorial Notes on Perl - Part B - XML in Client and Server Communication