關於C#建立FLASH服務端的安全沙箱問題

注意:XMLSocket 接收到服務端下發的數據時,將連續放於接收緩衝區,直到接收到 "\0" 字節(字節內容爲 ASCII 值 0),才認爲接收完成,並調用相應的 onData 或 onXML 事件,因此,服務端使用標準的 String 類族,則在發送數據結尾應手動加上 "\0",同樣,當XMLSocket發送數據時,也會在數據的結尾自動加上"\0"。

1、允許FLASH訪問網絡


2、如果只是運行或者發佈成EXE,不調試,不會出現問題,調試之後出現安全沙箱問題

Flash Player 6 以上版本引入了安全策略文件,在進行正式的通信前,會檢查目標位置是否存在合法的安全策略,以防止不同域內的應用無限制任意互訪。

HTTP 方式下,Flash Player 會檢查目標域根目錄下是否存在 crossdomain.xml,如果有,則獲取並分析其內容(內容後述)以確定是否允許繼續訪問。

Socket 方式下,Flash Player 獲取安全策略稍微複雜些,從 9.0.115.0 版起,標準步驟如下(以下描述以 IE 爲標準,例外情況後述):
1) 首先向目標主機 843 端口發起連接,併發送一個字符串,內容爲 "<policy-file-request/>",並等待返回安全策略文件並分析。
2) 若 1) 失敗,則檢查 AS 代碼中是否使用了 Security.loadPolicyFile( "xmlsocket://主機:端口" ) 方法加載安全策略文件,若有,則獲取並分析。
3) 若 2) 失敗,則向 AS 代碼中即將連接的 "目標主機:端口" 發起請求,過程同 1)。
4) 若成功獲得安全策略文件並經分析認爲允許建立連接,則繼續執行 Connect() 方法,此時方真正嘗試創建與目標主機的連接。

解決方案:

1) 在服務端寫一個程序,監聽 843 端口,當收到 "<policy-file-request/>" 時將恰當的策略內容(crossdomain.xml)發送回客戶端。
2) 在 AS 中通過 loadPolicyFile() 加載策略文件,此處需注意使用 xmlsocket:// 而不是 http://。
3) 在標準服務端口中,檢測到 "<policy-file-request/>" 時,返回策略內容。


代碼如下

package{
  import flash.display.Sprite;
  import flash.events.*;
  import flash.net.XMLSocket;
  import flash.system.Security;
  public class ceshi extends Sprite {

    private var socket:XMLSocket;

    public function ceshi() {
		
		//Security.allowDomain("localhost:10000");
		btn.addEventListener(MouseEvent.CLICK,onClick)
      socket = new XMLSocket();
     
      // Add an event listener to be notified when the connection is made
      socket.addEventListener( Event.CONNECT, onConnect );
     
      // Connect to the server
      socket.connect( "localhost", 10000 );
	  
    }
   
   private function onClick(event:MouseEvent):void
   {
	   trace("點擊鼠標了")
	   socket.send("12321321321321321");
   }
   
    private function onConnect( event:Event ):void {
		Security.loadPolicyFile("xmlsocket://localhost:843");
      trace( "The xml socket is now connected..." );
    }
   
  }
}

C# 新建線程執行下面函數

        private void BeginSafe()
        {
            string host = "127.0.0.1";
            int port = 843;
            byte[] data;
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            Socket sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sc.Bind(ipe);
            sc.Listen(5);
            while (serverFlag)
            {
                Thread.Sleep(100);
                data = new byte[1024];
                Socket clientSocket = sc.Accept();

                int count = clientSocket.Receive(data, data.Length, 0);//接收的字節                
                string recstr = Encoding.UTF8.GetString(data, 0, count);//byte[]轉換成string 
                if (recstr.IndexOf("<policy-file-request/>") >= 0)
                {
                    byte[] datas = System.Text.Encoding.UTF8.GetBytes("<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"10000\" /></cross-domain-policy>\0");
                    clientSocket.Send(datas);
                    clientSocket.Close();                    
                    continue;
                }                 
            }
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章