[이 글은 이전에 쓰던 블로그에서 작성된 이후 새 블로그로 이전된 글입니다.]

Alternativa 습작
하루만에 이정도면 잘한건가

가끔씩 면이 제대로 정렬이 안 되는데 왜 이러는지 아시는 분 ;ㅅ;

[이 글은 이전에 쓰던 블로그에서 작성된 이후 새 블로그로 이전된 글입니다.]

갑자기 3D가 급 끌려서 동영상 강좌를 보고 따라해 본 예제

방향키로 화면 조정 가능

[이 글은 이전에 쓰던 블로그에서 작성된 이후 새 블로그로 이전된 글입니다.]

사실 코드만 공개해도 되지만, 플래시의 보안 정책에 대한 이해 없이 코드만 본다면 아무런 도움이 안 될 것 같아서 설명하다 보니 조금 길어졌네요

다큐멘트 클래스처럼 적용시킵니다. AIR 설정에서 ‘포함된 파일’ 부분에 ‘policy.xml’ 이름을 가진 정책 파일 형태의 파일을 넣어주세요.

MIT 라이센스하에 배포하구요, 이것만 가지고는 소켓 서버를 못 만듭니다. 그냥 정책 파일 보내는 예제입니다.

정책 파일 보내는 포트와 실제 연결 포트가 다르다고 가정하고 짠 소스입니다.

클라이언트 측에서는 Security.loadPolicyFile("xmlsocket://127.0.0.1:843"); 등의 형태로 정책 파일을 요청하면 됩니다.

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent
    import flash.events.ServerSocketConnectEvent;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.ServerSocket;
    import flash.net.Socket;

    import fl.controls.TextArea;

    public class MySocketServer extends Sprite {
        private const TARGET_IP:String = "127.0.0.1"; //타겟 IP

        private var policyServer:ServerSocket;
        private const POLICY_PORT:int = 843; //타겟 포트

        public function MySocketServer():void {
            policyServer.addEventListener(ServerSocketConnectEvent.CONNECT, onPolicyConnected);
            policyServer.addEventListener(Event.CLOSE, serverClosed);

            policyServer.bind(POLICY_PORT, TARGET_IP); //서버 소켓을 바인드시킵니다.
            policyServer.listen();
        }

        private function onPolicyConnected(e:ServerSocketConnectEvent):void {
            var tmpSocket:Socket = e.socket as Socket;

            tmpSocket.addEventListener(ProgressEvent.SOCKET_DATA, policyDataHandler); //소켓의 정책 파일 요청을 감지합니다.
            tmpSocket.addEventListener(Event.CLOSE, onPolicyClosed);
            tmpSocket.addEventListener(IOErrorEvent.IO_ERROR, IOErrorOccured);
        }

        private function policyDataHandler(e:ProgressEvent):void {
            var tmpSocket:Socket = e.target as Socket;

            var message:String = tmpSocket.readUTFBytes(tmpSocket.bytesAvailable);

            sendPolicyFileTo(tmpSocket);
        }

        private function onPolicyClosed(e:Event):void {
            var tmpSocket:Socket = e.target as Socket;

            tmpSocket.removeEventListener(ProgressEvent.SOCKET_DATA, policyDataHandler);
            tmpSocket.removeEventListener(Event.CLOSE, onPolicyClosed);
            tmpSocket.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorOccured);
        }

        private function IOErrorOccured(event:IOErrorEvent):void {
            trace("IOError : " + event.text);
        }

        private function sendPolicyFileTo(target:Socket):void {
            //AIR FLA 안에 정책 파일의 형태로 policy.xml을 넣어주세요.
            //AIR2 설정의 포함된 파일 부분에 넣으시면 됩니다.

            var file:File = new File(File.applicationDirectory.nativePath + File.separator + "policy.xml");
            var stream:FileStream = new FileStream();
            stream.open(file, FileMode.READ);
            var data:String = stream.readUTFBytes(stream.bytesAvailable);

            target.writeUTFBytes(data);
            target.writeByte(0);
            target.flush(); //소켓에 정책 파일을 보냅니다.
        }
    }
}

[이 글은 이전에 쓰던 블로그에서 작성된 이후 새 블로그로 이전된 글입니다.]

정책 파일은 서버 내에 여러 개 위치할 수 있습니다. 플래시 플레이어에서 연결을 요청하면 기본적으로 루트 도메인의 /crossdomain.xml이라는 URL 정책 파일과 포트 843에서 소켓 정책 파일을 찾습니다.

정책 파일 중 이러한 정책 파일들을 ‘마스터 정책 파일’이라고 합니다.

소켓 연결의 경우 소켓 연결 위치와 같은 포트에서도 정책 파일을 찾지만, 이러한 정책 파일은 ‘마스터 정책 파일’로 간주되지 않습니다.

마스터 정책 파일은 일반적인 액세스 지정 외에도 메타 정책 문이 포함될 수 있습니다. 이 ‘메타 정책 문’에서 서버 내의 정책 파일들의 권한을 지정할 수 있습니다.

URL 정책 파일

URL 정책 파일에 대한 기본 메타 정책은 master-only이므로, 마스터 정책 파일 이외의 다른 정책 파일들은 무시됩니다.

플래시 플레이어 9 까지 URL 정책 파일에 대한 기본 메타 정책은 all이었으나,
사용자가 서버에 crossdomain.xml을 업로드 -> 그 crossdomain.xml을 정책 파일로 사용 -> 서버 데이터 접근
과 같은 방식으로 악용될 수 있어 플래시 플레이어 10에서 바뀌게 되었습니다.

보다 자세한 사항은 링크를 참조하세요.

swf 파일에서 Security.loadPolicyFile()을 이용해 다른 정책파일이나 다른 디렉터리 위치를 참조할 수 있습니다. 그러나 마스터 정책 파일에서 허용된 파일이 아니라면 이 요청은 무시됩니다.

(myserver.com/flash/crossdomain.xml을 로드 요청 하더라도 myserver.com/crossdomain.xml에서 메타 정책이 허용되어 있어야 함)

마스터 정책 파일을 확인할 때 플래시 플레이어는 3초간 서버 응답을 기다리고, 서버 응답이 없다면 마스터 정책 파일이 없다고 간주합니다.

그러나 loadPolicyFile()를 사용할 경우 플래시 플레이어는 호출되는 파일이 있다고 가정하고 파일을 로드하는데 필요한 시간동안 기다립니다. 따라서 loadPolicyFile()를 사용하여 명시적으로 파일을 호출하는 방법을 권장합니다.

소켓 정책 파일

플래시 플레이어는 연결을 요청하면 포트 843에서 제공되는 소켓 정책 파일을 찾습니다. URL 정책 파일과 마찬가지로 이것을 마스터 정책 파일이라 합니다.

URL 정책 파일과 마찬가지로 소켓 정책 파일은 정책 파일을 제공할 수 있는 포트를 지정할 수 있는 메타 정책 문을 지원합니다. 하지만 소켓 정책 파일의 기본 메타 정책은 all이므로, 마스터 정책 파일에서 제한을 두지 않는 한 모든 포트에서 정책 파일 로드가 가능합니다.

플래시 플레이어는 연결 요청 시 포트 843과 연결이 요청된 포트에서 소켓 정책 파일을 찾습니다. 다른 포트에서 정책 파일을 찾으려면 다음과 같이 loadPolidyFile()을 이용해 포트를 지정해 주어야 합니다.

Security.loadPolicyFile("xmlsocket://myserver.com:2525");

소켓 서버를 구현하고 소켓 정책 파일을 제공해야 할 필요가 있는 경우 연결되는 소켓과 같은 포트에서 정책 파일을 제공할 지 아니면 다른 포트에서 제공할 지를 결정해야 합니다. 두 경우 모두 서버에서 소켓 정책 파일을 보내기 전 클라이언트의 요청을 기다려야 합니다.

플래시 플레이어에서 연결을 요청할 때는 항상 연결이 설정된 직후 다음 문자열을 전송합니다.
<policy-file-request/>

플래시 플레이어의 요청은 null 바이트로 종료되며, 서버의 응답도 null 바이트로 종료되어야 합니다.

참조

링크 1
링크 2