I'm working on a multi-user app, and using sockets for communication. I can connect fine when using either localhost, 127.0.0.1, or my IP when running the swf from the harddrive. I need to be able to server a response to the <policy-file-request> to be able to connect across domains. I can't use the standard http method since the final socket server may be on a server with no http server (load balancing is still in the works).

How do you format the response to the <policy-file-request> when using a PHP socket server? Do I need to send XML headers first, or just the XML itself?

Here's the server code:
PHP Code:
#!/usr/bin/php -q
<?php

error_reporting
(E_ALL);

set_time_limit(0);

ob_implicit_flush();

$address '192.168.2.4';
$port 9999;

//---- Function to Send out Messages to Everyone Connected ----------------------------------------
function send_Message($allclient$buf) {
  global 
$client_list;
  foreach(
$allclient as $client) {
    if(
$client_list[$client]['state'] && $client_list[$client]['nick'] != ""){
      
socket_write($clienttrim($buf).chr(0));
    }
  }
}

//---- Function to Send List of  Everyone Connected ----------------------------------------
function who($allclient$socket) {
  global 
$client_list;
  
$buf "";
  
$counter 0;
  foreach(
$allclient as $client) {
    
$buf.=$client_list[$client]['nick'].", ";
    
$counter++;
  }
  
socket_write($socket"There are $counter people in this room: $buf".chr(0));
}

//---- Function to Send out Messages to Individuals ----------------------------------------
function send_Single($socket$buf) {
  
socket_write($socket$buf.chr(0));
}



//---- Start Socket creation for PHP 5 Socket Server -------------------------------------

if (($master socket_create(AF_INETSOCK_STREAMSOL_TCP)) < 0) {
  echo 
"socket_create() failed, reason: " socket_strerror($master) . "\n";
}

socket_set_option($masterSOL_SOCKET,SO_REUSEADDR1);


if ((
$ret socket_bind($master$address$port)) < 0) {
  echo 
"socket_bind() failed, reason: " socket_strerror($ret) . "\n";
}


if ((
$ret socket_listen($master5)) < 0) {
  echo 
"socket_listen() failed, reason: " socket_strerror($ret) . "\n";
}



$read_sockets = array($master);
$client_list = array($master);

//---- Create Persistent Loop to continuously handle incoming socket messages ---------------------
while (true) {
  
$changed_sockets $read_sockets;

  
$num_changed_sockets socket_select($changed_sockets$write NULL$except NULLNULL);

  foreach(
$changed_sockets as $socket) {

    if (
$socket == $master) {

      
//---- Accept Incoming Connections and Request Nickname ----------------------------------------
      
if (($client socket_accept($master)) < 0) {
        echo 
"socket_accept() failed: reason: " socket_strerror($msgsock) . "\n";
        continue;
      } else {
    echo 
"[connection]:$client\n";
        
array_push($read_sockets$client);
    
$client_list[$client]['state'] = false;
    
send_Single($client"<b>Enter a nickname:<b>");
      }
    } else {

      
//---- Grab Incoming Messages From all Users ----------------------------------------
      
$bytes socket_recv($socket$buffer20480);

      
//---- Handle User Disconnects ----------------------------------------
      
if ($bytes == 0) {
    
$nick $client_list[$socket]['nick'];
        
$iindex array_search($socket$client_list);
        unset(
$client_list[$iindex]);
        
$index array_search($socket$read_sockets);
        unset(
$read_sockets[$index]);
        
socket_close($socket);
        
$allclients $read_sockets;
        
array_shift($allclients);
    if(
$client_list[$socket]['nick'] != "" && $client_list[$socket]['nick'] != "<policy-file-request/>"){
          
send_Message($allclients"$nick has left the room");
    }
      }else{
    if(
$bytes){
          
//---- Set Nickname ----------------------------------------
      
if($client_list[$socket]['state'] === false){
        
$client_list[$socket]['nick'] = $tempBuf trim(trim($buffer));
        echo 
$tempBuf." test";
        
send_Single($socket"Hello $tempBuf!  Welcome to the game!");
            
$allclients $read_sockets;
            
array_shift($allclients);
        
who($allclients$socket);
        if(
$client_list[$socket]['nick'] != "" && $tempBuf != "<policy-file-request/>"){
              
send_Message($allclients$client_list[$socket]['nick']." has entered the game.");
        }
        
$client_list[$socket]['state'] = true;
      }else{
            
//---- Check Message for Commands, and Respond or Broadcast Message ----------------------------------------
            
$allclients $read_sockets;
            
array_shift($allclients);
        if(
trim($buffer) == "/who"){
          
who($allclients$socket);
        }else{
              
send_Message($allclients$client_list[$socket]['nick']." wrote: ".$buffer);
        }
      }
    }
      }
    }
  }
}

?>
Here's the AS3 chat class (compiled with Flex/mxmlc):
PHP Code:
package{

    
import flash.display.*;
    
import flash.events.*;
    
import flash.text.*;
    
import flash.net.*;

    public class 
chat extends Sprite {

        private var 
socket:XMLSocket;
        private var 
msgArea:TextField = new TextField();
        private var 
inputMsg:TextField = new TextField();
        private var 
lastMessage:String "";
        private var 
connected:Boolean false;

        public function 
chat() {
            
msgArea.x=15;
            
msgArea.y=15;
            
msgArea.width=450;
            
msgArea.height=150;
            
msgArea.multiline=msgArea.border=msgArea.background=true;
            
addChild(msgArea);

            
inputMsg.x=15;
            
inputMsg.y=170;
            
inputMsg.width=415;
            
inputMsg.height=20;
            
inputMsg.type=TextFieldType.INPUT;
            
inputMsg.multiline=false;
            
inputMsg.selectable=inputMsg.border=inputMsg.background=true;
            
inputMsg.text="192.168.2.4";
            
addChild(inputMsg);

            var 
pushMsg:Sprite = new Sprite();
            var 
pushText:TextField = new TextField();
            
pushText.x=400;
            
pushText.y=170;
            
pushText.selectable=false;
            
pushText.autoSize='center';
            
pushText.text='Send';
            
pushText.border=pushText.background=true;
            
pushMsg.useHandCursor=true;
            
pushMsg.addChild(pushText);
            
pushMsg.addEventListener(MouseEvent.MOUSE_DOWNmsgGo);
            
addChild(pushMsg);

            
socket = new XMLSocket();
            
configureListeners(socket);
            
msgArea.htmlText lastMessage "<b>Enter IP address of the server, then click the \"Send\" button</b>";

        }

            private function 
configureListeners(dispatcher:IEventDispatcher):void {
                    
dispatcher.addEventListener(Event.CLOSEcloseHandler);
                    
dispatcher.addEventListener(Event.CONNECTconnectHandler);
                    
dispatcher.addEventListener(DataEvent.DATAdataHandler);
            
dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERRORsecurityErrorHandler);
               }

        private function 
securityErrorHandler(event:SecurityErrorEvent):void {
            
msgArea.htmlText += "<br>securityErrorHandler: " event;
        }

        private function 
connectHandler(success:Boolean):void 
            if (
success) { 
                
msgArea.htmlText lastMessage '<br>' '<b>Server connection established!</b>'
                
lastMessage '<b>Server connection established!</b>';
                
connected true;
            } else { 
                
msgArea.htmlText lastMessage '<br>' '<b>Server connection failed!</b>'
                
lastMessage '<b>Server connection failed!</b>';
            } 
        } 

        private function 
closeHandler(event:Event):void 
            
msgArea.htmlText lastMessage '<br>' '<b>Server connection lost</b>'
            
lastMessage '<b>Server connection lost</b>';
        } 

        private function 
dataHandler(event:DataEvent):void 
            
msgArea.htmlText lastMessage '<br>' event.data;
            
lastMessage event.data
        } 

        private function 
msgGo(event:MouseEvent):void{
            if(!
connected){
                
msgArea.htmlText lastMessage "<b>Contacting Server...</b>";
                
socket.connect(inputMsg.text,9999);
            }else{
                if (
inputMsg.text != '') { 
                    
socket.send(inputMsg.text); 
                } 
            }
            
inputMsg.text ''
        }

    }

And here's the AS2 version (compiled with Ming/PHP):
PHP Code:
<?

ming_useswfversion(7);
$movie=new SWFMovie(7);
$movie->setDimension(550,200);
$movie->setBackground(255,255,255);
$movie->setRate(30);

$actions="

createTextField('msgArea', getNextHighestDepth(), 15, 17, 450, 150);
with(msgArea){
border=background=html=wordWrap=mulitline=selectable=multiline=wordWrap=true;
}

createTextField('inputMsg', getNextHighestDepth(), 15, 170, 415, 20);
with(inputMsg){
border=background=true;
multiline=false;
type='input';
text='192.168.2.4';
}
inputMsg.onKeyPress=function(){
if(Key.isDown(Key.ENTER)){
pushMsg.onRelease();
}
};

createEmptyMovieClip('pushMsg',getNextHighestDepth());
pushMsg.createTextField('buttonText', pushMsg.getNextHighestDepth(), 455, 170, 0, 0);
with(pushMsg.buttonText){
border=background=true;
selectable=false;
autoSize='center';
text='Send';
}

mySocket = new XMLSocket(); 
connected = false;

mySocket.onConnect = function(success) { 
if (success) { 
msgArea.htmlText = lastMessage + '\n' + '<b>Server connection established!</b>'; 
lastMessage = '<b>Server connection established!</b>';
connected = true;
} else { 
msgArea.htmlText = lastMessage + '\n' + '<b>Server connection failed!</b>'; 
lastMessage = '<b>Server connection failed!</b>';

}; 
  
mySocket.onClose = function() { 
msgArea.htmlText = lastMessage + '\n' + '<b>Server connection lost</b>'; 
lastMessage = '<b>Server connection lost</b>';
}; 
  
var lastMessage = '';
XMLSocket.prototype.onData = function(msg) { 
  msgArea.htmlText = lastMessage + '\n' + msg;
  lastMessage = msg; 
}; 
  
msgArea.text = lastMessage = 'Enter IP address of the server, then click the \"Send\" button';
  
//--- Handle button click -------------------------------------- 
  
function msgGO() { 
if(!connected){
msgArea.htmlText = lastMessage = '<b>Contacting Server...</b>';
mySocket.connect(inputMsg.text, 9999); 
}else{
if (inputMsg.text != '') { 
mySocket.send(inputMsg.text); 
}
}
inputMsg.text = '';

  
pushMsg.onRelease = function() { 
msgGO(); 
Selection.setFocus(inputMsg);
}; 

_keyListener = new Object();
Key.addListener(_keyListener);
_keyListener.onKeyDown=function(){
if(Key.getCode()==Key.ENTER){
pushMsg.onRelease();
}
};
  
";
$movie->add(new SWFAction($actions));

// save swf with same name as filename
$swfname = basename(__FILE__,".php");
$movie->save($outswf="$swfname.swf",9);
// open movie and set version to 8 
// (hack until it can be set in ming)
$ftmp=fopen($outswf,"r"); 
$stmp=fread($ftmp,filesize($outswf));
$ftmp=fopen($outswf,"w"); 
fwrite($ftmp,substr_replace($stmp,chr(8),3,1));

$revitalizer=rand();
print "<html><body bgColor=\"#c6c6c6\"><center>
<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=8,0,0,0\" ID=objects WIDTH=\"550\" HEIGHT=\"200\">
<PARAM NAME=movie VALUE=\"$outswf?r=$revitalizer\">
<EMBED src=\"$outswf?r=$revitalizer\" WIDTH=\"550\" HEIGHT=\"200\" TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\">
</OBJECT>
<br><br>
<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=9,0,0,0\" ID=objects WIDTH=\"550\" HEIGHT=\"200\">
<PARAM NAME=movie VALUE=\"../flex/bin/chat.swf?r=$revitalizer\">
<EMBED src=\"../flex/bin/chat.swf?r=$revitalizer\" WIDTH=\"550\" HEIGHT=\"200\" TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\">
</OBJECT>
</center></body></html>
";
?>
Note- the above code outputs HTML to display both AS2 & AS3 versions on the same page, but only compiles the AS2 version via Ming.