我有需要打開一個組插座到本地機器上運行的Flash應用程序的Eclipse插件。 Flash需要一個策略文件(XML blob)來授予訪問相關端口的權限。閃存更喜歡得到這個策略文件通過端口843,爪哇把港口< 1024個作爲特權端口和Mac OS X和Linux類似的限制訪問,我不希望運行我的root權限Eclipse插件端口< 1024,因此服務起來端口843上的策略文件不是一個選項。據Adobe稱,文檔,如果Flash不能得到端口843的策略文件,它回落到請求的端口上的政策文件,它嘗試連接。 ActionScript代碼看起來是這樣的:如何從Eclipse插件提供Flash策略文件?
/**
* Connecting to some port to communicate with the debugger. We initiate the
* connection because Flex doesn't allow us to listen to any ports.
*/
private function initSockets():void
{
requestSocket = new Socket();
requestSocket.addEventListener(Event.CONNECT, requestConnected);
requestSocket.addEventListener(Event.CLOSE, closed);
requestSocket.addEventListener(ProgressEvent.SOCKET_DATA, processRequestData);
requestSocket.addEventListener(IOErrorEvent.IO_ERROR, ioError);
requestSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError);
requestSocket.connect("localhost", SCConstants.DEBUG_LESSON_REQUEST_PORT);
eventSocket = new Socket();
eventSocket.addEventListener(Event.CONNECT, eventConnected);
eventSocket.addEventListener(Event.CLOSE, closed);
eventSocket.addEventListener(ProgressEvent.SOCKET_DATA, processEventData);
eventSocket.addEventListener(IOErrorEvent.IO_ERROR, ioError);
eventSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError);
eventSocket.connect("localhost", SCConstants.DEBUG_LESSON_EVENT_PORT);
}
在我繼承了一些代碼,作品在OS X上的時間大部分Eclipse插件的一面,但有時會失敗在Windows上。在Wi-Fi而不是有線以太網上運行也往往會失敗,儘管我不知道爲什麼這很重要。
public Boolean connect() throws DebugException {
try {
try {
// connection code
fRequestServerSocket = new ServerSocket(requestPort);
fRequestServerSocket.setSoTimeout(ACCEPT_TIMEOUT);
fEventServerSocket = new ServerSocket(eventPort);
fEventServerSocket.setSoTimeout(ACCEPT_TIMEOUT);
TWBLogger.logInfo("Open socket request server:" + fRequestServerSocket);
TWBLogger.logInfo("Open socket event server:" + fEventServerSocket);
String policy = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<cross-domain-policy>\n" +
"<allow-access-from domain=\"*\" to-ports=\"5000,5001\" secure=\"false\" />\n" +
"</cross-domain-policy>\0";
// Because of the Flash security policy the first thing
// that will accept on the socket will be the Flash Player
// trying to verify us. The Flash player will request security
// policy file with the following string: <policy-file-request/>\0
// We will serve back the above policy file and then close the socket
// The next thing to accept is our process in the VM.
fRequestSocket = fRequestServerSocket.accept();
fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
// Wait some time before giving flash the policy file. Otherwise they don't get it. ;(
// 3 is too much ... ;(
Thread.sleep(100);
fRequestWriter.print(policy);
fRequestWriter.flush();
fRequestSocket.close();
// this should be the real connection
fRequestSocket = fRequestServerSocket.accept();
TWBLogger.logInfo("Open socket request:" + fRequestSocket);
fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
// the same situation for the EventSocket
fEventSocket = fEventServerSocket.accept();
fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream()));
TWBLogger.logInfo("Open socket event:" + fEventSocket);
} catch (SocketTimeoutException e) {
TWBLogger.logWaring("Connection to the Client Timed out.");
cleanSockets();
return false;
requestFailed("Connection to the VM timed out. Please close any other running lessons that you debug and try again", e);
} catch (SocketSecurityException e) {
requestFailed("Security error occured when connecting to the VM", e);
} catch (Exception e) {
if (!fTerminated)
requestFailed("Error occured when connecting to the VM. Please close any other running lessons that you debug.", e);
}
} catch (DebugException e) {
// close the sockets so that we can debug another application
cleanSockets();
throw e;
}
// our VM is single threaded
fThread = new TWBThread(this);
fThreads = new IThread[] {fThread};
// start listening for events from the VM
fEventDispatch = new EventDispatchJob();
fEventDispatch.schedule();
// start listening for breakpoints
IBreakpointManager breakpointManager = getBreakpointManager();
breakpointManager.addBreakpointListener(this);
breakpointManager.addBreakpointManagerListener(this);
return true;
}
此代碼看起來不正確。它不會等待來自Flash的消息,而只是將策略響應阻塞到端口中。正如我所說,它大部分時間都在運行,但它有時會失敗,似乎不符合Adobe的文檔。
我嘗試偵聽每個端口上請求數據包和發送端口特定響應。我使用WireShark在環回接口(Mac OS X)上觀察套接字通信量。我看到了策略請求和收到的響應,但Flash仍然在兩個端口上給我安全沙箱違例。
我也試着在上面所示的initSockets的開始加入這一行:
Security.loadPolicyFile("xmlsocket://localhost:5002");
然後,我在我的插件添加的代碼爲偵聽端口5002和發送以下主策略文件內容:
private final static String FLASH_POLICY_RESPONSE =
"<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n" +
"<cross-domain-policy>\n" +
"<site-control permitted-cross-domain-policies=\"master-only\"/>\n" +
"<allow-access-from domain=\"*\" to-ports=\"5000,5001\"/>\n" +
"</cross-domain-policy>\0";
再次只見請求進來和響應出去,但是Flash似乎並未對此作出迴應。我沒有收到安全沙箱違例錯誤,但也沒有通過端口的流量。
任何人都可以啓發我在Java和Flash之間打開套接字的正確方法嗎?