|
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
|