#!/usr/bin/perl ########################################## # #
by phil on Wednesday Jul 30, 2003 12:29 AM
#!/usr/bin/perl##########################################
#
# Flash sometimes has problems communicating
# to traditional TCP/IP XML servers. This is
# is because each packet that the Flash clients
# print to servers are ended by a "\0" while as
# server's traditionally recognize "\n" as the
# end. Example, in Perl, if you go $line =
# $line will usually contain one line of the file
# where a line is whatever's delimited by \n's.
# Also, when reading data back, Flash only
# recognizes data if it's delimited by "\0"'s as
# well. Lame, I know.
#
# This program relays communication back
# and forth between flash clients and standard
# servers. There is an XML parsing issue that
# also has to be taken into account as each
# XML packet that comes from the server needs
# to be delimited with \0's. I've attempted
# to take care of this as you'll see below..
# it hasn't been rigorously tested though
# so use at your own risk...
#
# I'm not the greatest programmer, and there
# may be blocking issues... so, please improve.
#
# I got most of this junk from Advanced Perl
# Programming by O'Reilly.
#
# - Philip Dhingra (philipd@stanford.edu)
# http://www.philosophistry.com/
#
# Keywords: XMLSocket
###########################################use IO::Socket;
use IO::Select;$remote_rs = "\n";
$flash_rs = "\0";# XML tags that I want to be sent to Flash
@root_headers = ('Q','O','M');# $/ denotes the input record separator (default: '\n')
# $\ denotes the output record separater (default: null)
# Flash separates records with a \0
# Standard TCP/IP servers use the default, \nclose STDOUT; # if you don't want to see what's going on
$remote_host = 'whatever.com';
$remote_port = '6969';$local_port = '9696';
$flash_sock = new IO::Socket::INET (Listen => SOMAXCONN,
Proto => 'tcp',
Reuse => 1,
LocalPort => $local_port)
or die ("**STATUS: Flash Listening Server could not start");
sub open_remote_sock {return new IO::Socket::INET (Proto => 'tcp',
PeerAddr => $remote_host,
PeerPort => $remote_port)
or die ("**STATUS: Cannot Connect to Remote Server (" . $remote_host . ":" . $remote_port);}
print "**STATUS: Flash Listening Server started\n" if ($flash_sock);
$read_set = new IO::Select;
$read_set->add($flash_sock);while(1) {
($new_readable) = IO::Select->select($read_set, undef, undef, undef);
foreach $readable (@$new_readable) {
if ($readable == $flash_sock) {
$flash_client = $flash_sock->accept();$read_set->add($flash_client);
print "**STATUS: Flash connection from: " . $flash_client->peerhost . "\n";$read_set->add($remote_sock = &open_remote_sock);
print "**STATUS: Connected to Remote Server\n" if ($remote_sock);} elsif ($readable == $remote_sock) {
$/ = $remote_rs;
$from_remote = <$remote_sock>;
chomp $from_remote;
if ($from_remote eq '') {
print "**STATUS: Remote Server connection lost**";
$remote_sock->close;
exit;
} else {
print "(-): " . $from_remote . "\n";# BEGIN XML parsing..
if ($waiting_for) {
$queue .= $from_remote;
} else {
$queue = $from_remote;
}$waiting_for = hasRootHeaders($from_remote) unless ($waiting_for);
if ($waiting_for) {
if ($queue =~ s/(<$waiting_for>.*?<\/$waiting_for>)//s) {print $flash_client $1 . $flash_rs;
$flash_client->flush();$waiting_for = hasRootHeaders($queue);
}
}# END XML parsing
}
# Flash client is trying to speak...
} elsif ($readable == $flash_client) {
$/ = $flash_rs;
$from_flash = <$readable>;
chomp($from_flash);
if ($from_flash eq '') {
print "**STATUS: Connection to Flash Client (" . $flash_client->peerhost . ") lost\n";
$read_set->remove($readable);
$readable->close;# closing remote socket
$read_set->remove($remote_sock);
$remote_sock->close;
} else {
print "(+): " . $from_flash . "\n";
print $remote_sock $from_flash . $remote_rs;
$remote_sock->flush();}
# Dead client is trying to speak
} else {
print "**STATUS: Connection to Flash Client (" . $readable->peerhost . ") lost\n";
$read_set->remove($readable);
$readable->close;
# closing remote socket
$read_set->remove($remote_sock);
$remote_sock->close;
}
}
}
sub hasRootHeaders {
my $snippet = shift;
my @matches;foreach $key (@root_headers) {
if ($snippet =~ m#$key>#) {
$tail_key = $key;
}
}
foreach $key (@root_headers) {
if ($snippet =~ m#<$key>#) {
push @matches, $key;
}
}
foreach $match (@matches) {
return $match if ($match eq $tail_key);
}return pop(@matches) if (@matches);
return '';
}sub drainReadBuffer {
my $sock = shift;
my $bytes_to_read = 1024;
my $msg;
}
Keywords: flash, record separator, null terminator, xmlsocket, xml server, relay
Comments
majid khossravi said on February 22, 2004 6:49 AM:
how swf file within a html can communicate this server , i mean XMLSocket connection doesnt work if i wont execute perl file befor