Original: http://hi.baidu.com/mr%5Fziqiang/blog/item/7a2c4baf2c4a21fdfbed501e.html
When I did the test yesterday, I encountered a problem. The SWF was successfully debugged in Flash as3, but the data could not be obtained after being published to HTML. After checking some information, I found a solution. Here, I would like to thank Jian Xin for his help and his colleagues, if Shui three thousand, for providing Java code and log records.
1. Problem Description
After flash is published in HTML format, SwF cannot communicate with the server through socket after the page is loaded. The Flash end displays the following error:
Securityerrorhandler information: [securityerrorevent type = "securityerror" Bubbles = false cancelable = false eventphase = 2 text = "Error #2048"]
The information displayed on the server is that the client tries to connect but cannot accept the data. The accepted data is displayed as null.
2. cause:
The latest Flash Player 9.0.124.0. When the Flash file requires socket communication, you need to obtain the crossdomain. xml file from the server. The client cannot connect to the server if it cannot be found.
Understand the three processes of Flash socket communication
When flash encapsulated in the page initiates a socket communication request, it first looks for port 843 on the server side to obtain crossdomain. XML file. When 843 is not enabled on the server, flashplayer checks whether security is used in the SWF file that initiates the request. loadpolicyfile to load the crossdomain policy file. XML. If not, check whether there is a policy file on the target port to be connected to the SWF that initiates the request. If none of them are connected, the above error message is returned.
Why is there no such problem in the old Flash Player version?
I learned from some official documents. In the past, Flash Player shared a security policy file regardless of whether you use URLRequest HTTP or xmlsocket socket. This policy file can be stored in the directory of the primary domain. But not now. If you use the HTTP request method, you need to put the policy file under the directory. If you use the socket request method, you must use the socket port to receive the policy file.
The corresponding call method is:
HTTP request -- "security. loadpolicyfile (" http://www.xxx.com/crossdomain.xml ")
Socket or xmlsocket request -- Security. loadpolicyfile ("xmlsocket: // www.xxx.com: Port ")
How to send socke policy files to Flash Player
Flash Player in your socket. before connect ("Domain", Port) is run, according to the three procedures described above, we will send port 843 to your socket server (it is said that Adobe has applied to relevant authorities to retain port 843 for Flash Player) send a string "<policy-file-Request/>". If you have a service listening for port 843, after receiving this string, simply send back the policy file in XML format. (Remember to add an ending character "\ 0" when sending back the message ")
Of course, you can also set a port without using port 843. If Flash Player cannot obtain information on port 843, it will check whether you have added a specified channel to your flash file. You can define a port. However, you cannot use HTTP instead of xmlsocket. (It is equivalent to automatically creating an xmlsocket object for you and then linking the host and port you specified ). For example, if you want to use port 1234, you can add this security statement in your flash. loadpolicyfile ("xmlsocket: // www.xxx.com: 1234"). Note that this sentence should be added to your socket. before connect.
The last method is to listen to this request on your socket connection port. For example, you are using socket. connect ("192.168.1.100", 8888), add a piece of code to your server to receive the string "<policy-file-Request/>, when this string is received, the policy writer sends it to the client in XML format.
About the format of the policy file (you can find it in Flash Player Security in Flash CS3 -- "control permission overview)
1. Policy files for Web Applications
The following example shows a policy file that allows access to SWF files from * .iflashigame.com and 192.0.34.166.
<? XML version = "1.0"?>
<Cross-domain-Policy>
<Allow-access-from domain = "* .iflashigame.com"/>
<Allow-access-from domain = "192.0.34.166"/>
</Cross-Domain-Policy>
Note:
By default, the policy file must be named crossdomain. xml and located in the root directory of the server. However, you can call security. loadpolicyfile () to check whether the SWF file is another name or is in another directory. The cross-origin policy file is only applicable to the directory from which the file is loaded and Its subdirectories. Therefore, the policy file in the root directory applies to the entire server, but the policy file loaded from any subdirectory only applies to this directory and Its subdirectories.
The policy file only affects access to a specific server. For example, a policy file located in https://www.adobe.com: 8080/crossdomain. xml only applies to data loading calls to http://www.adobe.com/over HTTPS on port 8080.
2. socket-specific policy files
<Cross-domain-Policy>
<Allow-access-from domain = "*" to-ports = "507"/>
<Allow-access-from domain = "* .example.com" to-ports = "507,516"/>
<Allow-access-from domain = "* .example2.com" to-ports = "516-523"/>
<Allow-access-from domain = "http://www.example2.com/" to-ports = "507,516-523"/>
<Allow-access-from domain = "http://www.example3.com/" to-ports = "*"/>
</Cross-Domain-Policy>
This policy file specifies the domains that hosts are allowed to use the port links.
References
Flash xmlsocket Policy
Policy file changes in Flash Player 9
Setting up a socket policy file server
Understanding Flash Player 9 release L 2008 Security Update compatibility
How to change and handle the flex socket security policy after flash player is upgraded to 9.0.124
Obtain the Java server code of the policy file
Import java. Io. bufferedreader;
Import java. Io. bufferedwriter;
Import java. Io. ioexception;
Import java. Io. inputstreamreader;
Import java. Io. outputstreamwriter;
Import java.net. serversocket;
Import java.net. Socket;
Public class securityxmlserver implements runnable {
Private serversocket server;
Private bufferedreader reader;
Private bufferedwriter writer;
Private string XML;
Public securityxmlserver ()
{
String Path = "yyfile file path ";
// Replace this with the corresponding method for reading XML documents, such as Dom or sax.
// Xml = readfile (path, "UTF-8 ");
/**
Note that the content of the XML file here is a pure string and there is no XML document version number.
*/
Xml = "<cross-domain-Policy>"
+ "<Allow-access-from domain = \" * \ "to-ports = \" 1025-9999 \ "/>"
+ "</Cross-Domain-Policy> ";
System. Out. println ("policyfile file path:" + path );
System. Out. println (XML );
// Start port 843
Createserversockets (843 );
New thread (this). Start ();
}
// Start the server
Private void createserversocket (INT port)
{
Try {
Server = new serversocket (port );
System. Out. println ("service listening port:" + port );
} Catch (ioexception e ){
System. Exit (1 );
}
}
// Start the server thread
Public void run ()
{
While (true ){
Socket Client = NULL;
Try {
// Receive client connection
Client = server. Accept ();
Inputstreamreader input = new inputstreamreader (client. getinputstream (), "UTF-8 ");
Reader = new bufferedreader (input );
Outputstreamwriter output = new outputstreamwriter (client. getoutputstream (), "UTF-8 ");
Writer = new bufferedwriter (output );
// Read the data sent by the client
Stringbuilder DATA = new stringbuilder ();
Int C = 0;
While (C = reader. Read ())! =-1)
{
If (C! = '\ 0 ')
Data. append (char) C );
Else
Break;
}
String info = data. tostring ();
System. Out. println ("input request:" + info );
// Send the policy file after receiving the request from the client
If (info. indexof ("<policy-file-Request/>")> = 0)
{
Writer. Write (XML + "\ 0 ");
Writer. Flush ();
System. Out. println ("Send the security policy file to:" + client. getinetaddress ());
}
Else
{
Writer. Write ("the request cannot be identified \ 0 ");
Writer. Flush ();
System. Out. println ("the request cannot be identified:" + client. getinetaddress ());
}
Client. Close ();
} Catch (exception e ){
E. printstacktrace ();
Try {
// Closes the connection when an exception is found
If (client! = NULL ){
Client. Close ();
Client = NULL;
}
} Catch (ioexception ex ){
Ex. printstacktrace ();
} Finally {
// Call the garbage collection method
System. GC ();
}
}
}
}
// Test the main function
Public static void main (string [] ARGs)
{
New securityxmlserver ();
}
}