java flash 安全沙箱

flash底层安全机制强制要求flash通信或者跨域访问时,必须从服务端拿到安全策略文件,默认是flash会向服务端843发送<policy-file-request/>报文,当服务端843不开放,或者安全时间(3秒)内无返回时,如果是socket通信,flash会向服务端socket指定端口发送请求报文<policy-file-request/>,如果服务端无返回或返回不是安全策略文件,那么flash将报安全沙箱错误。安全策略文件内容如下:

<cross-domain-policy>

<allow-access-from domain="*" to-ports="*"/>

</cross-domain-policy>

其中domain指定可访问的跨域地址,to-ports为指定可访问的跨域端口,

java服务端一般做法是开启843端口服务,网上代码如下:(此代码测试有严重的bug,下面会指出)

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;
 private int stop = 0;

 public SecurityXMLServer() {
  xml = "<cross-domain-policy>"
    + "<allow-access-from domain=\"*\" to-ports=\"*\"/>"
    + "</cross-domain-policy>\0";

  // System.out.println(xml);

  // 启动843端口
  createServerSocket(843);
  new Thread(this).start();
 }

 // 启动服务器
 private void createServerSocket(int port) {
  try {
   server = new ServerSocket(port);
   System.out.println("服务监听843端口:" + port);
  } catch (IOException e) {
   e.printStackTrace();
   try {
    server.close();
   } catch (IOException e1) {
    e1.printStackTrace();
   }
  }
 }

 // 启动服务器线程
 public void run() {
  while (true) {
   if (stop == 1)
    break;

   Socket client = null;
   try {
    // 接收客户端的连接
    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);

    // 读取客户端发送的数据
    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("收到的请求: " + info);

    // 接收到客户端的请求之后,将策略文件发送出去
    if (info.indexOf("<policy-file-request/>") >= 0) {
     writer.write(xml);
     writer.flush();
     // System.out.println("将安全策略文件发送至: " +
     // client.getInetAddress());
    } else {
     writer.write("Quest Error \0");
     writer.flush();
     // System.out.println("请求无法识别: "+client.getInetAddress());
    }
    client.close();
   } catch (Exception e) {
    try {
     // 发现异常关闭连接
     if (client != null) {
      client.close();
      client = null;
     }
    } catch (IOException ex) {
     ex.printStackTrace();
    }
   }
  }
 }

 public ServerSocket getServer() {
  return server;
 }

 public void setStop(int stop) {
  this.stop = stop;
 }

}

这段代码的bug出现在单线程监听843,一旦客户端假死,简单可测试的方法就是连上后突然断线,停电,那么843端口被占用,无法访问,主要是  while ((c = reader.read()) != -1)

reader.read()当TCP异常时,是无法监测到的,断线/停电等情况都会造成reader.read()阻塞,客户端无消息到达,服务端也无法监测到客户端的状态,所以会一直阻塞,之前我的一个项目就是因为用同样的方式去读取843安全请求信息,所以经常出现843阻塞,得靠重启843服务来维护。其实Socket中有一个方法,setSoTimeout(毫秒),此方法设置了连接超时时间,

默认是setSoTimeout(0),只要在client = server.accept();后面加client.setSoTimeout(300);就不会再出现843阻塞无法连接的情况了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值