flash发起socket通讯的三个过程:
1、当封装在页面的flash发起socket通讯请求的时候会寻找服务器端843端口, 获取crossdomain.xml文件。
2、当服务器没有开启843的时候,flash player会检查发起请求的swf文件中有没有使用Security.loadPolicyFile(xmlsocket://127.0.0.1:4299)
来加载策略文件crossdomain.xml。
3、如果没有就会看这个发起请求的swf要连接的目标端口有没有策略文件。
如果上述三个步骤都没有找到策略文件,那么出现连接失败并出现错误提示:
[SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"]
新版的flash player,当flash文件要进行socket通讯的时候,需要向服务器端 获取crossdomain.xml文件,如果找不到就会出现上述问题。
(老版的flash player无论你采用的是http请求方式或者xmlsocket socket方式, 他们都共用一个安全策略文件,这个策略文件只要你放在主域的目录下就行,
而新版的要求,如果你使用http请求方式需要把策略文件放在目录下面,如果你使用的socket请求方式就必须通过socket端口来接收这个策略文件。
其对应的调用的方式为:
http请求:Security.loadPolicyFile("http://www.xxx.com/crossdomain.xml");
socket或xmlsocket请求:Security.loadPolicyFile("xmlsocket://www.xxx.com:port");)
三种方法:
一、使用默认843端口
flash player在你的socket.connect(address,port);运行之前,会按照三个过程向你的socket 服务器的843端口发送一个字符串 "
这个时候如果你有一个服务器在监听843端口那么受到这个字符串之后,直接按照xml格式发挥策略文件就解决了。
二、使用自定义端口(推荐使用)
当然你也可以自己设置一个端口,不过这个时候不能用Http方式,而要用xmlsocket方式。相当于自动帮你新建一个xmlsocket对象,
然后连接你指定的主机和端口, 比如你想用1234端口可以在你的flash里面加这一句Security.loadPolicyFile("xmlsocket://www.xxx.com:1234")
需要注意的是这一句要加在你的socket.connect()前面。
三、代码发送策略文件。
在你的socket连接端口监听这个请求,比如你用的是socekt.connect("127.0.0.1",3333);
那么在你的服务器加一段接受字符串"
1、针对web应用的策略文件
示列为策略文件允许访问源自:*game.com和192.168.1.1的swf文件
注意事项:
默认情况下,策略文件必须命名为 crossdomain.xml,并且必须位于服务器的根目录中。但是,SWF 文件可以通过调用
Security.loadPolicyFile() 方法检查是否为其它名称或位于 其它目录中。跨域策略文件仅适用于从其中加载该文件的目录
及其子目录。因此,根目录中的策略文件适用于整个服务器, 但是从任意子目录加载的策略文件仅适用于该目录及其子目录。
2、针对socket的策略文件
这个策略文件是指定允许哪些域的主机通过哪些端口链接。
java socket服务端:
安全策略服务器:
public class SecurityServer
{
private int count = 0;
public String xml = "";
private InputStream is;
private OutputStream os;
public void start() throws Exception
{
xml += "";
xml += " ";
xml += " ";
ServerSocket serverSocket = new ServerSocket(4299);
System.out.println("等待用户连接``并发送策略文件``````");
while (true)
{
try
{
Socket socket = serverSocket.accept();
count++;
this.is = socket.getInputStream();
this.os = socket.getOutputStream();
byte[] temp = new byte[300];
this.is.read(temp);
this.os.write(this.xml.getBytes("utf-8"));
this.os.flush();
this.os.close();
this.is.close();
socket.close();
} catch (Exception e)
{
System.out.println("服务器发生异常");
}
}
}
public static void main(String[] args)
{
try
{
new SecurityServer().start();
} catch (Exception e)
{
System.out.println("Socket发生异常:" + e);
}
}
}
主连接服务器:
public class ServerJava
{
private int count =0;
public void start() throws Exception
{
ServerSocket serverSocket = new ServerSocket(4399);
System.out.println("等待用户连接````````");
while (true)
{
try
{
Socket socket = serverSocket.accept();
count++;
System.out.println("连接成功``数量: `````"+count);
ServerThread thread = new ServerThread(socket);
thread.start();
} catch (Exception e)
{
System.out.println("服务器发生异常");
}
}
}
public static void main(String[] args)
{
try
{
new ServerJava().start();
} catch (Exception e)
{
System.out.println("Socket发生异常:" + e);
}
}
}
服务端读取客户端数据:
public class ServerThread extends Thread
{
private Socket socket;
private BufferedReader input;
private PrintWriter output;
private OutputStream os;
private InputStream is;
public ServerThread(Socket socket)
{
this.socket = socket;
}
public void run()
{
System.out.println("---------------启动一个线程-----------------");
try
{
this.os = this.socket.getOutputStream();
this.is = this.socket.getInputStream();
byte[] temp = new byte[1000];
int len = 0;
StringBuffer msg = new StringBuffer();
while ((len = this.is.read(temp)) > 0)
{
msg.append(new String(temp, 0, len,"UTF-8"));
if(len<1000){
this.os.write(msg.toString().getBytes("UTF-8"));
this.os.flush();
msg = new StringBuffer();
}
}
} catch (Exception e)
{
System.out.println("子线程发生异常");
try
{
input.close();
output.close();
} catch (Exception ex)
{
System.out.println("关闭资源发生异常");
}
System.out.println("子线程结束了");
}
}
}
as3客户单端代码:
package {
import flash.net.Socket;
import flash.events.ProgressEvent;
import flash.events.Event;
import flash.utils.ByteArray;
import flash.display.Sprite;
import flash.system.Security;
import flash.text.TextField;
import flash.events.MouseEvent;
public class ClientSocket extends Sprite {
private var count:uint=0;
private var clientSocket:Socket;
private var readBytes:ByteArray = new ByteArray();
private var writeBytes:ByteArray = new ByteArray();
public function ClientSocket() {
conn.addEventListener(MouseEvent.CLICK,connServer);
send.addEventListener(MouseEvent.CLICK,sendToServer);
}
private function connServer(evt:MouseEvent):void {
clientSocket = new Socket();
Security.allowDomain("*");
Security.loadPolicyFile("xmlsocket://127.0.0.1:4299")
clientSocket.connect("127.0.0.1",4399);
clientSocket.addEventListener(Event.CONNECT,successConn);
clientSocket.addEventListener(ProgressEvent.SOCKET_DATA,reviceData);
}
private function successConn(evt:Event):void {
count++;
dyText.text="连接成功"+count+"\n";
}
private function sendToServer(evt:Event):void {
var charContext=inputText.text;
dyText.text=dyText.text+charContext+"\n";
//utf-8转码
clientSocket.writeUTFBytes(charContext);
clientSocket.flush();
}
private function reviceData(evt:Event):void {
trace(totalLen+"======revice message===============");
var totalLen:uint=clientSocket.bytesAvailable;
server.text=clientSocket.readUTFBytes(totalLen);
}
}
}